提交 c9b95e59 编写于 作者: L Linus Torvalds

Merge tag 'sound-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound updates from Takashi Iwai:
 "The majority of this update is about ASoC, including a few new
  drivers, and the rest are mostly minor changes.  The only substantial
  change in ALSA core is about the additional error handling in the
  compress-offload API.  Below are highlights:

   - Add the error propagating support in compress-offload API

   - HD-audio: a usual Dell headset fixup, an Intel HDMI/DP fix, and the
     default mixer setup change ot turn off the loopback

   - Lots of updates for ASoC Intel drivers, mostly board support and
     bug fixing, and to the NAU8825 driver

   - Work on generalizing bits of simple-card to allow more code sharing
     with the Renesas rsrc-card (which can't use simple-card due to DPCM)

   - Removal of the Odroid X2 driver due to replacement with simple-card

   - Support for several new Mediatek platforms and associated boards

   - New ASoC drivers for Allwinner A10, Analog Devices ADAU7002,
     Broadcom Cygnus, Cirrus Logic CS35L33 and CS53L30, Maxim MAX8960
     and MAX98504, Realtek RT5514 and Wolfson WM8758"

* tag 'sound-4.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (278 commits)
  sound: oss: Use kernel_read_file_from_path() for mod_firmware_load()
  ASoC: Intel: Skylake: Delete an unnecessary check before the function call "release_firmware"
  ASoC: Intel: Skylake: Fix NULL Pointer exception in dynamic_debug.
  ASoC: samsung: Specify DMA channels through struct snd_dmaengine_pcm_config
  ASoC: samsung: Fix error paths in the I2S driver's probe()
  ASoC: cs53l30: Fix bit shift issue of TDM mode
  ASoC: cs53l30: Fix a bug for TDM slot location validation
  ASoC: rockchip: correct the spdif clk
  ALSA: echoaudio: purge contradictions between dimension matrix members and total number of members
  ASoC: rsrc-card: use asoc_simple_card_parse_card_name()
  ASoC: rsrc-card: use asoc_simple_dai instead of rsrc_card_dai
  ASoC: rsrc-card: use asoc_simple_card_parse_dailink_name()
  ASoC: simple-card: use asoc_simple_card_parse_card_name()
  ASoC: simple-card-utils: add asoc_simple_card_parse_card_name()
  ASoC: simple-card: use asoc_simple_card_parse_dailink_name()
  ASoC: simple-card-utils: add asoc_simple_card_set_dailink_name()
  ASoC: nau8825: drop redundant idiom when converting integer to boolean
  ASoC: nau8825: jack connection decision with different insertion logic
  ASoC: mediatek: Add HDMI dai-links to the mt8173-rt5650 machine driver
  ASoC: mediatek: mt2701: fix non static symbol warning
  ...
......@@ -13,6 +13,11 @@ Required properties:
- reg: The i2c address. Value depends on the state of ADDR0
and ADDR1, as wired in hardware.
Optional properties:
- clock-names: If provided must be "mclk".
- clocks: phandle + clock-specifiers for the clock that provides
the audio master clock for the device.
Examples:
#include <dt-bindings/sound/adau17x1.h>
......@@ -20,5 +25,8 @@ Examples:
adau1361@38 {
compatible = "adi,adau1761";
reg = <0x38>;
clock-names = "mclk";
clocks = <&audio_clock>;
};
};
Analog Devices ADAU7002 Stereo PDM-to-I2S/TDM Converter
Required properties:
- compatible: Must be "adi,adau7002"
Optional properties:
- IOVDD-supply: Phandle and specifier for the power supply providing the IOVDD
supply as covered in Documentation/devicetree/bindings/regulator/regulator.txt
If this property is not present it is assumed that the supply pin is
hardwired to always on.
Example:
adau7002: pdm-to-i2s {
compatible = "adi,adau7002";
IOVDD-supply = <&supply>;
};
BROADCOM Cygnus Audio I2S/TDM/SPDIF controller
Required properties:
- compatible : "brcm,cygnus-audio"
- #address-cells: 32bit valued, 1 cell.
- #size-cells: 32bit valued, 0 cell.
- reg : Should contain audio registers location and length
- reg-names: names of the registers listed in "reg" property
Valid names are "aud" and "i2s_in". "aud" contains a
set of DMA, I2S_OUT and SPDIF registers. "i2s_in" contains
a set of I2S_IN registers.
- clocks: PLL and leaf clocks used by audio ports
- assigned-clocks: PLL and leaf clocks
- assigned-clock-parents: parent clocks of the assigned clocks
(usually the PLL)
- assigned-clock-rates: List of clock frequencies of the
assigned clocks
- clock-names: names of 3 leaf clocks used by audio ports
Valid names are "ch0_audio", "ch1_audio", "ch2_audio"
- interrupts: audio DMA interrupt number
SSP Subnode properties:
- reg: The index of ssp port interface to use
Valid value are 0, 1, 2, or 3 (for spdif)
Example:
cygnus_audio: audio@180ae000 {
compatible = "brcm,cygnus-audio";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x180ae000 0xafd>, <0x180aec00 0x1f8>;
reg-names = "aud", "i2s_in";
clocks = <&audiopll BCM_CYGNUS_AUDIOPLL_CH0>,
<&audiopll BCM_CYGNUS_AUDIOPLL_CH1>,
<&audiopll BCM_CYGNUS_AUDIOPLL_CH2>;
assigned-clocks = <&audiopll BCM_CYGNUS_AUDIOPLL>,
<&audiopll BCM_CYGNUS_AUDIOPLL_CH0>,
<&audiopll BCM_CYGNUS_AUDIOPLL_CH1>,
<&audiopll BCM_CYGNUS_AUDIOPLL_CH2>;
assigned-clock-parents = <&audiopll BCM_CYGNUS_AUDIOPLL>;
assigned-clock-rates = <1769470191>,
<0>,
<0>,
<0>;
clock-names = "ch0_audio", "ch1_audio", "ch2_audio";
interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
ssp0: ssp_port@0 {
reg = <0>;
status = "okay";
};
ssp1: ssp_port@1 {
reg = <1>;
status = "disabled";
};
ssp2: ssp_port@2 {
reg = <2>;
status = "disabled";
};
spdif: spdif_port@3 {
reg = <3>;
status = "disabled";
};
};
......@@ -4,7 +4,7 @@ This device support generic Bluetooth SCO link.
Required properties:
- compatible : "delta,dfbmcs320"
- compatible : "delta,dfbmcs320" or "linux,bt-sco"
Example:
......
CS35L33 Speaker Amplifier
Required properties:
- compatible : "cirrus,cs35l33"
- 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.
Optional properties:
- reset-gpios : gpio used to reset the amplifier
- interrupt-parent : Specifies the phandle of the interrupt controller to
which the IRQs from CS35L33 are delivered to.
- interrupts : IRQ line info CS35L33.
(See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
for further information relating to interrupt properties)
- cirrus,boost-ctl : Booster voltage use to supply the amp. If the value is
0, then VBST = VP. If greater than 0, the boost voltage will be 3300mV with
a value of 1 and will increase at a step size of 100mV until a maximum of
8000mV.
- cirrus,ramp-rate : On power up, it affects the time from when the power
up sequence begins to the time the audio reaches a full-scale output.
On power down, it affects the time from when the power-down sequence
begins to when the amplifier disables the PWM outputs. If this property
is not set then soft ramping will be disabled and ramp time would be
20ms. If this property is set to 0,1,2,3 then ramp times would be 40ms,
60ms,100ms,175ms respectively for 48KHz sample rate.
- cirrus,boost-ipk : The maximum current allowed for the boost converter.
The range starts at 1850000uA and goes to a maximum of 3600000uA
with a step size of 15625uA. The default is 2500000uA.
- cirrus,imon-adc-scale : Configures the scaling of data bits from the IMON
ADC data word. This property can be set as a value of 0 for bits 15 down
to 0, 6 for 21 down to 6, 7, for 22 down to 7, 8 for 23 down to 8.
Optional H/G Algorithm sub-node:
The cs35l33 node can have a single "cirrus,hg-algo" sub-node that will enable
the internal H/G Algorithm.
- cirrus,hg-algo : Sub-node for internal Class H/G algorithm that
controls the amplifier supplies.
Optional properties for the "cirrus,hg-algo" sub-node:
- cirrus,mem-depth : Memory depth for the Class H/G algorithm measured in
LRCLK cycles. If this property is set to 0, 1, 2, or 3 then the memory
depths will be 1, 4, 8, 16 LRCLK cycles. The default is 16 LRCLK cycles.
cirrus,release-rate : The number of consecutive LRCLK periods before
allowing release condition tracking updates. The number of LRCLK periods
start at 3 to a maximum of 255.
- cirrus,ldo-thld : Configures the signal threshold at which the PWM output
stage enters LDO operation. Starts as a default value of 50mV for a value
of 1 and increases with a step size of 50mV to a maximum of 750mV (value of
0xF).
- cirrus,ldo-path-disable : This is a boolean property. If present, the H/G
algorithm uses the max detection path. If not present, the LDO
detection path is used.
- cirrus,ldo-entry-delay : The LDO entry delay in milliseconds before the H/G
algorithm switches to the LDO voltage. This property can be set to values
from 0 to 7 for delays of 5ms, 10ms, 50ms, 100ms, 200ms, 500ms, 1000ms.
The default is 100ms.
- cirrus,vp-hg-auto : This is a boolean property. When set, class H/G VPhg
automatic updating is enabled.
- cirrus,vp-hg : Class H/G algorithm VPhg. Controls the H/G algorithm's
reference to the VP voltage for when to start generating a boosted VBST.
The reference voltage starts at 3000mV with a value of 0x3 and is increased
by 100mV per step to a maximum of 5500mV.
- cirrus,vp-hg-rate : The rate (number of LRCLK periods) at which the VPhg is
allowed to increase to a higher voltage when using VPhg automatic
tracking. This property can be set to values from 0 to 3 with rates of 128
periods, 2048 periods, 32768 periods, and 524288 periods.
The default is 32768 periods.
- cirrus,vp-hg-va : VA calculation reference for automatic VPhg tracking
using VPMON. This property can be set to values from 0 to 6 starting at
1800mV with a step size of 50mV up to a maximum value of 1750mV.
Default is 1800mV.
Example:
cs35l33: cs35l33@40 {
compatible = "cirrus,cs35l33";
reg = <0x40>;
VA-supply = <&ldo5_reg>;
VP-supply = <&ldo5_reg>;
interrupt-parent = <&gpio8>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
reset-gpios = <&cs47l91 34 0>;
cirrus,ramp-rate = <0x0>;
cirrus,boost-ctl = <0x30>; /* VBST = 8000mV */
cirrus,boost-ipk = <0xE0>; /* 3600mA */
cirrus,imon-adc-scale = <0> /* Bits 15 down to 0 */
cirrus,hg-algo {
cirrus,mem-depth = <0x3>;
cirrus,release-rate = <0x3>;
cirrus,ldo-thld = <0x1>;
cirrus,ldo-path-disable = <0x0>;
cirrus,ldo-entry-delay=<0x4>;
cirrus,vp-hg-auto;
cirrus,vp-hg=<0xF>;
cirrus,vp-hg-rate=<0x2>;
cirrus,vp-hg-va=<0x0>;
};
};
CS53L30 audio CODEC
Required properties:
- compatible : "cirrus,cs53l30"
- reg : the I2C address of the device
- VA-supply, VP-supply : power supplies for the device,
as covered in Documentation/devicetree/bindings/regulator/regulator.txt.
Optional properties:
- reset-gpios : a GPIO spec for the reset pin.
- mute-gpios : a GPIO spec for the MUTE pin. The active state can be either
GPIO_ACTIVE_HIGH or GPIO_ACTIVE_LOW, which would be handled
by the driver automatically.
- cirrus,micbias-lvl : Set the output voltage level on the MICBIAS Pin.
0 = Hi-Z
1 = 1.80 V
2 = 2.75 V
- cirrus,use-sdout2 : This is a boolean property. If present, it indicates
the hardware design connects both SDOUT1 and SDOUT2
pins to output data. Otherwise, it indicates that
only SDOUT1 is connected for data output.
* CS53l30 supports 4-channel data output in the same
* frame using two different ways:
* 1) Normal I2S mode on two data pins -- each SDOUT
* carries 2-channel data in the same time.
* 2) TDM mode on one signle data pin -- SDOUT1 carries
* 4-channel data per frame.
Example:
codec: cs53l30@48 {
compatible = "cirrus,cs53l30";
reg = <0x48>;
reset-gpios = <&gpio 54 0>;
VA-supply = <&cs53l30_va>;
VP-supply = <&cs53l30_vp>;
};
......@@ -12,6 +12,10 @@ Required properties:
one for receive.
- dma-names : "tx" for the transmit channel, "rx" for the receive channel.
Optional properties:
- interrupts: The interrupt line number for the I2S controller. Add this
parameter if the I2S controller that you are using does not support DMA.
For more details on the 'dma', 'dma-names', 'clock' and 'clock-names'
properties please check:
* resource-names.txt
......
......@@ -58,7 +58,7 @@ Required properties:
* DMIC (stands for Digital Microphone Jack)
Note: The "Mic Jack" and "AMIC" are redundant while
coexsiting in order to support the old bindings
coexisting in order to support the old bindings
of wm8962 and sgtl5000.
Optional properties:
......
Maxim MAX98504 class D mono speaker amplifier
This device supports I2C control interface and an IRQ output signal. It features
a PCM and PDM digital audio interface (DAI) and a differential analog input.
Required properties:
- compatible : "maxim,max98504"
- reg : should contain the I2C slave device address
- DVDD-supply, DIOVDD-supply, PVDD-supply: power supplies for the device,
as covered in ../regulator/regulator.txt
- interrupts : should specify the interrupt line the device is connected to,
as described in ../interrupt-controller/interrupts.txt
Optional properties:
- maxim,brownout-threshold - the PVDD brownout threshold, the value must be
from 0, 1...21 range, corresponding to 2.6V, 2.65V...3.65V voltage range
- maxim,brownout-attenuation - the brownout attenuation to the speaker gain
applied during the "attack hold" and "timed hold" phase, the value must be
from 0...6 (dB) range
- maxim,brownout-attack-hold-ms - the brownout attack hold phase time in ms,
0...255 (VBATBROWN_ATTK_HOLD, register 0x0018)
- maxim,brownout-timed-hold-ms - the brownout timed hold phase time in ms,
0...255 (VBATBROWN_TIME_HOLD, register 0x0019)
- maxim,brownout-release-rate-ms - the brownout release phase step time in ms,
0...255 (VBATBROWN_RELEASE, register 0x001A)
The default value when the above properties are not specified is 0,
the maxim,brownout-threshold property must be specified to actually enable
the PVDD brownout protection.
Example:
max98504@31 {
compatible = "maxim,max98504";
reg = <0x31>;
interrupt-parent = <&gpio_bank_0>;
interrupts = <2 0>;
DVDD-supply = <&regulator>;
DIOVDD-supply = <&regulator>;
PVDD-supply = <&regulator>;
};
MAX9860 Mono Audio Voice Codec
Required properties:
- compatible : "maxim,max9860"
- reg : the I2C address of the device
- AVDD-supply, DVDD-supply and DVDDIO-supply : power supplies for
the device, as covered in bindings/regulator/regulator.txt
- clock-names : Required element: "mclk".
- clocks : A clock specifier for the clock connected as MCLK.
Examples:
max9860: max9860@10 {
compatible = "maxim,max9860";
reg = <0x10>;
AVDD-supply = <&reg_1v8>;
DVDD-supply = <&reg_1v8>;
DVDDIO-supply = <&reg_3v0>;
clock-names = "mclk";
clocks = <&pck2>;
};
Mediatek AFE PCM controller for mt2701
Required properties:
- compatible = "mediatek,mt2701-audio";
- reg: register location and size
- interrupts: Should contain AFE interrupt
- clock-names: should have these clock names:
"infra_sys_audio_clk",
"top_audio_mux1_sel",
"top_audio_mux2_sel",
"top_audio_mux1_div",
"top_audio_mux2_div",
"top_audio_48k_timing",
"top_audio_44k_timing",
"top_audpll_mux_sel",
"top_apll_sel",
"top_aud1_pll_98M",
"top_aud2_pll_90M",
"top_hadds2_pll_98M",
"top_hadds2_pll_294M",
"top_audpll",
"top_audpll_d4",
"top_audpll_d8",
"top_audpll_d16",
"top_audpll_d24",
"top_audintbus_sel",
"clk_26m",
"top_syspll1_d4",
"top_aud_k1_src_sel",
"top_aud_k2_src_sel",
"top_aud_k3_src_sel",
"top_aud_k4_src_sel",
"top_aud_k5_src_sel",
"top_aud_k6_src_sel",
"top_aud_k1_src_div",
"top_aud_k2_src_div",
"top_aud_k3_src_div",
"top_aud_k4_src_div",
"top_aud_k5_src_div",
"top_aud_k6_src_div",
"top_aud_i2s1_mclk",
"top_aud_i2s2_mclk",
"top_aud_i2s3_mclk",
"top_aud_i2s4_mclk",
"top_aud_i2s5_mclk",
"top_aud_i2s6_mclk",
"top_asm_m_sel",
"top_asm_h_sel",
"top_univpll2_d4",
"top_univpll2_d2",
"top_syspll_d5";
Example:
afe: mt2701-afe-pcm@11220000 {
compatible = "mediatek,mt2701-audio";
reg = <0 0x11220000 0 0x2000>,
<0 0x112A0000 0 0x20000>;
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>;
clocks = <&infracfg CLK_INFRA_AUDIO>,
<&topckgen CLK_TOP_AUD_MUX1_SEL>,
<&topckgen CLK_TOP_AUD_MUX2_SEL>,
<&topckgen CLK_TOP_AUD_MUX1_DIV>,
<&topckgen CLK_TOP_AUD_MUX2_DIV>,
<&topckgen CLK_TOP_AUD_48K_TIMING>,
<&topckgen CLK_TOP_AUD_44K_TIMING>,
<&topckgen CLK_TOP_AUDPLL_MUX_SEL>,
<&topckgen CLK_TOP_APLL_SEL>,
<&topckgen CLK_TOP_AUD1PLL_98M>,
<&topckgen CLK_TOP_AUD2PLL_90M>,
<&topckgen CLK_TOP_HADDS2PLL_98M>,
<&topckgen CLK_TOP_HADDS2PLL_294M>,
<&topckgen CLK_TOP_AUDPLL>,
<&topckgen CLK_TOP_AUDPLL_D4>,
<&topckgen CLK_TOP_AUDPLL_D8>,
<&topckgen CLK_TOP_AUDPLL_D16>,
<&topckgen CLK_TOP_AUDPLL_D24>,
<&topckgen CLK_TOP_AUDINTBUS_SEL>,
<&clk26m>,
<&topckgen CLK_TOP_SYSPLL1_D4>,
<&topckgen CLK_TOP_AUD_K1_SRC_SEL>,
<&topckgen CLK_TOP_AUD_K2_SRC_SEL>,
<&topckgen CLK_TOP_AUD_K3_SRC_SEL>,
<&topckgen CLK_TOP_AUD_K4_SRC_SEL>,
<&topckgen CLK_TOP_AUD_K5_SRC_SEL>,
<&topckgen CLK_TOP_AUD_K6_SRC_SEL>,
<&topckgen CLK_TOP_AUD_K1_SRC_DIV>,
<&topckgen CLK_TOP_AUD_K2_SRC_DIV>,
<&topckgen CLK_TOP_AUD_K3_SRC_DIV>,
<&topckgen CLK_TOP_AUD_K4_SRC_DIV>,
<&topckgen CLK_TOP_AUD_K5_SRC_DIV>,
<&topckgen CLK_TOP_AUD_K6_SRC_DIV>,
<&topckgen CLK_TOP_AUD_I2S1_MCLK>,
<&topckgen CLK_TOP_AUD_I2S2_MCLK>,
<&topckgen CLK_TOP_AUD_I2S3_MCLK>,
<&topckgen CLK_TOP_AUD_I2S4_MCLK>,
<&topckgen CLK_TOP_AUD_I2S5_MCLK>,
<&topckgen CLK_TOP_AUD_I2S6_MCLK>,
<&topckgen CLK_TOP_ASM_M_SEL>,
<&topckgen CLK_TOP_ASM_H_SEL>,
<&topckgen CLK_TOP_UNIVPLL2_D4>,
<&topckgen CLK_TOP_UNIVPLL2_D2>,
<&topckgen CLK_TOP_SYSPLL_D5>;
clock-names = "infra_sys_audio_clk",
"top_audio_mux1_sel",
"top_audio_mux2_sel",
"top_audio_mux1_div",
"top_audio_mux2_div",
"top_audio_48k_timing",
"top_audio_44k_timing",
"top_audpll_mux_sel",
"top_apll_sel",
"top_aud1_pll_98M",
"top_aud2_pll_90M",
"top_hadds2_pll_98M",
"top_hadds2_pll_294M",
"top_audpll",
"top_audpll_d4",
"top_audpll_d8",
"top_audpll_d16",
"top_audpll_d24",
"top_audintbus_sel",
"clk_26m",
"top_syspll1_d4",
"top_aud_k1_src_sel",
"top_aud_k2_src_sel",
"top_aud_k3_src_sel",
"top_aud_k4_src_sel",
"top_aud_k5_src_sel",
"top_aud_k6_src_sel",
"top_aud_k1_src_div",
"top_aud_k2_src_div",
"top_aud_k3_src_div",
"top_aud_k4_src_div",
"top_aud_k5_src_div",
"top_aud_k6_src_div",
"top_aud_i2s1_mclk",
"top_aud_i2s2_mclk",
"top_aud_i2s3_mclk",
"top_aud_i2s4_mclk",
"top_aud_i2s5_mclk",
"top_aud_i2s6_mclk",
"top_asm_m_sel",
"top_asm_h_sel",
"top_univpll2_d4",
"top_univpll2_d2",
"top_syspll_d5";
};
MT2701 with CS42448 CODEC
Required properties:
- compatible: "mediatek,mt2701-cs42448-machine"
- mediatek,platform: the phandle of MT2701 ASoC platform
- audio-routing: a list of the connections between audio
- mediatek,audio-codec: the phandles of cs42448 codec
- mediatek,audio-codec-bt-mrg the phandles of bt-sco dummy codec
- pinctrl-names: Should contain only one value - "default"
- pinctrl-0: Should specify pin control groups used for this controller.
- i2s1-in-sel-gpio1, i2s1-in-sel-gpio2: Should specify two gpio pins to
control I2S1-in mux.
Example:
sound:sound {
compatible = "mediatek,mt2701-cs42448-machine";
mediatek,platform = <&afe>;
/* CS42448 Machine name */
audio-routing =
"Line Out Jack", "AOUT1L",
"Line Out Jack", "AOUT1R",
"Line Out Jack", "AOUT2L",
"Line Out Jack", "AOUT2R",
"Line Out Jack", "AOUT3L",
"Line Out Jack", "AOUT3R",
"Line Out Jack", "AOUT4L",
"Line Out Jack", "AOUT4R",
"AIN1L", "AMIC",
"AIN1R", "AMIC",
"AIN2L", "Tuner In",
"AIN2R", "Tuner In",
"AIN3L", "Satellite Tuner In",
"AIN3R", "Satellite Tuner In",
"AIN3L", "AUX In",
"AIN3R", "AUX In";
mediatek,audio-codec = <&cs42448>;
mediatek,audio-codec-bt-mrg = <&bt_sco_codec>;
pinctrl-names = "default";
pinctrl-0 = <&aud_pins_default>;
i2s1-in-sel-gpio1 = <&pio 53 0>;
i2s1-in-sel-gpio2 = <&pio 54 0>;
};
MT8173 with RT5650 CODECS
MT8173 with RT5650 CODECS and HDMI via I2S
Required properties:
- compatible : "mediatek,mt8173-rt5650"
- mediatek,audio-codec: the phandles of rt5650 codecs
and of the hdmi encoder node
- mediatek,platform: the phandle of MT8173 ASoC platform
Optional subnodes:
......@@ -12,12 +13,17 @@ Required codec-capture subnode properties:
<&rt5650 0> : Default setting. Connect rt5650 I2S1 for capture. (dai_name = rt5645-aif1)
<&rt5650 1> : Connect rt5650 I2S2 for capture. (dai_name = rt5645-aif2)
- mediatek,mclk: the MCLK source
0 : external oscillator, MCLK = 12.288M
1 : internal source from mt8173, MCLK = sampling rate*256
Example:
sound {
compatible = "mediatek,mt8173-rt5650";
mediatek,audio-codec = <&rt5650>;
mediatek,audio-codec = <&rt5650 &hdmi0>;
mediatek,platform = <&afe>;
mediatek,mclk = <0>;
codec-capture {
sound-dai = <&rt5650 1>;
};
......
......@@ -8,6 +8,8 @@ Required properties:
- interrupts: Interrupt number for McPDM
- interrupt-parent: The parent interrupt controller
- ti,hwmods: Name of the hwmod associated to the McPDM
- clocks: phandle for the pdmclk provider, likely <&twl6040>
- clock-names: Must be "pdmclk"
Example:
......@@ -19,3 +21,11 @@ mcpdm: mcpdm@40132000 {
interrupt-parent = <&gic>;
ti,hwmods = "mcpdm";
};
In board DTS file the pdmclk needs to be added:
&mcpdm {
clocks = <&twl6040>;
clock-names = "pdmclk";
status = "okay";
};
......@@ -373,6 +373,8 @@ Optional properties:
- #clock-cells : it must be 0 if your system has audio_clkout
it must be 1 if your system has audio_clkout0/1/2/3
- clock-frequency : for all audio_clkout0/1/2/3
- clkout-lr-asynchronous : boolean property. it indicates that audio_clkoutn
is asynchronizes with lr-clock.
SSI subnode properties:
- interrupts : Should contain SSI interrupt for PIO transfer
......
......@@ -23,6 +23,11 @@ Required properties:
- rockchip,playback-channels: max playback channels, if not set, 8 channels default.
- rockchip,capture-channels: max capture channels, if not set, 2 channels default.
Required properties for controller which support multi channels
playback/capture:
- rockchip,grf: the phandle of the syscon node for GRF register.
Example for rk3288 I2S controller:
i2s@ff890000 {
......
......@@ -8,6 +8,11 @@ Required properties:
- reg : The I2C address of the device.
Optional properties:
- clocks: The phandle of the master clock to the CODEC
- clock-names: Should be "mclk"
Pins on the device (for linking into audio routes) for RT5514:
* DMIC1L
......
Samsung Exynos Odroid X2/U3 audio complex with MAX98090 codec
Required properties:
- compatible : "samsung,odroidx2-audio" - for Odroid X2 board,
"samsung,odroidu3-audio" - for Odroid U3 board
- samsung,model : the user-visible name of this sound complex
- samsung,i2s-controller : the phandle of the I2S controller
- samsung,audio-codec : the phandle of the MAX98090 audio codec
- samsung,audio-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 and sinks are the MAX98090's pins (as
documented in its binding), and the jacks on the board
For Odroid X2:
* Headphone Jack
* Mic Jack
* DMIC
For Odroid U3:
* Headphone Jack
* Speakers
Example:
sound {
compatible = "samsung,odroidu3-audio";
samsung,i2s-controller = <&i2s0>;
samsung,audio-codec = <&max98090>;
samsung,model = "Odroid-X2";
samsung,audio-routing =
"Headphone Jack", "HPL",
"Headphone Jack", "HPR",
"IN1", "Mic Jack",
"Mic Jack", "MICBIAS";
};
......@@ -7,6 +7,14 @@ Required properties:
- clocks : the clock provider of SYS_MCLK
- VDDA-supply : the regulator provider of VDDA
- VDDIO-supply: the regulator provider of VDDIO
Optional properties:
- VDDD-supply : the regulator provider of VDDD
- micbias-resistor-k-ohms : the bias resistor to be used in kOmhs
The resistor can take values of 2k, 4k or 8k.
If set to 0 it will be off.
......@@ -15,17 +23,9 @@ Required properties:
- micbias-voltage-m-volts : the bias voltage to be used in mVolts
The voltage can take values from 1.25V to 3V by 250mV steps
If this node is not mentionned or the value is unknown, then
If this node is not mentioned or the value is unknown, then
the value is set to 1.25V.
- VDDA-supply : the regulator provider of VDDA
- VDDIO-supply: the regulator provider of VDDIO
Optional properties:
- VDDD-supply : the regulator provider of VDDD
Example:
codec: sgtl5000@0a {
......
......@@ -33,11 +33,11 @@ Required properties:
"tx" for "st,sti-uni-player" compatibility
"rx" for "st,sti-uni-reader" compatibility
- version: IP version integrated in SOC.
- st,version: IP version integrated in SOC.
- dai-name: DAI name that describes the IP.
- IP mode: IP working mode depending on associated codec.
- st,mode: IP working mode depending on associated codec.
"HDMI" connected to HDMI codec and support IEC HDMI formats (player only).
"SPDIF" connected to SPDIF codec and support SPDIF formats (player only).
"PCM" PCM standard mode for I2S or TDM bus.
......@@ -47,7 +47,7 @@ Required properties ("st,sti-uni-player" compatibility only):
- clocks: CPU_DAI IP clock source, listed in the same order than the
CPU_DAI properties.
- uniperiph-id: internal SOC IP instance ID.
- st,uniperiph-id: internal SOC IP instance ID.
Optional properties:
- pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for
......@@ -84,9 +84,9 @@ Example:
dmas = <&fdma0 4 0 1>;
dai-name = "Uni Player #2 (DAC)";
dma-names = "tx";
uniperiph-id = <2>;
version = <5>;
mode = "PCM";
st,uniperiph-id = <2>;
st,version = <5>;
st,mode = "PCM";
};
sti_uni_player3: sti-uni-player@3 {
......@@ -100,9 +100,9 @@ Example:
dmas = <&fdma0 7 0 1>;
dma-names = "tx";
dai-name = "Uni Player #3 (SPDIF)";
uniperiph-id = <3>;
version = <5>;
mode = "SPDIF";
st,uniperiph-id = <3>;
st,version = <5>;
st,mode = "SPDIF";
};
sti_uni_reader1: sti-uni-reader@1 {
......@@ -115,7 +115,7 @@ Example:
dmas = <&fdma0 6 0 1>;
dma-names = "rx";
dai-name = "Uni Reader #1 (HDMI RX)";
version = <3>;
st,version = <3>;
st,mode = "PCM";
};
......
* Allwinner A10 I2S controller
The I2S bus (Inter-IC sound bus) is a serial link for digital
audio data transfer between devices in the system.
Required properties:
- compatible: should be one of the followings
- "allwinner,sun4i-a10-i2s"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: should contain the I2S interrupt.
- dmas: DMA specifiers for tx and rx dma. See the DMA client binding,
Documentation/devicetree/bindings/dma/dma.txt
- dma-names: should include "tx" and "rx".
- clocks: a list of phandle + clock-specifer pairs, one for each entry in clock-names.
- clock-names: should contain followings:
- "apb" : clock for the I2S bus interface
- "mod" : module clock for the I2S controller
- #sound-dai-cells : Must be equal to 0
Example:
i2s0: i2s@01c22400 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun4i-a10-i2s";
reg = <0x01c22400 0x400>;
interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&apb0_gates 3>, <&i2s0_clk>;
clock-names = "apb", "mod";
dmas = <&dma SUN4I_DMA_NORMAL 3>,
<&dma SUN4I_DMA_NORMAL 3>;
dma-names = "rx", "tx";
};
......@@ -3,7 +3,7 @@ ASoC Machine Driver
The ASoC machine (or board) driver is the code that glues together all the
component drivers (e.g. codecs, platforms and DAIs). It also describes the
relationships between each componnent which include audio paths, GPIOs,
relationships between each component which include audio paths, GPIOs,
interrupts, clocking, jacks and voltage regulators.
The machine driver can contain codec and platform specific code. It registers
......
......@@ -14,7 +14,7 @@ provides a refined estimate with a delay.
event or application query.
The difference (tstamp - trigger_tstamp) defines the elapsed time.
The ALSA API provides reports two basic pieces of information, avail
The ALSA API provides two basic pieces of information, avail
and delay, which combined with the trigger and current system
timestamps allow for applications to keep track of the 'fullness' of
the ring buffer and the amount of queued samples.
......@@ -53,21 +53,21 @@ case):
The analog time is taken at the last stage of the playback, as close
as possible to the actual transducer
The link time is taken at the output of the SOC/chipset as the samples
The link time is taken at the output of the SoC/chipset as the samples
are pushed on a link. The link time can be directly measured if
supported in hardware by sample counters or wallclocks (e.g. with
HDAudio 24MHz or PTP clock for networked solutions) or indirectly
estimated (e.g. with the frame counter in USB).
The DMA time is measured using counters - typically the least reliable
of all measurements due to the bursty natured of DMA transfers.
of all measurements due to the bursty nature of DMA transfers.
The app time corresponds to the time tracked by an application after
writing in the ring buffer.
The application can query what the hardware supports, define which
The application can query the hardware capabilities, define which
audio time it wants reported by selecting the relevant settings in
audio_tstamp_config fields, get an estimate of the timestamp
audio_tstamp_config fields, thus get an estimate of the timestamp
accuracy. It can also request the delay-to-analog be included in the
measurement. Direct access to the link time is very interesting on
platforms that provide an embedded DSP; measuring directly the link
......@@ -169,7 +169,7 @@ playback: systime: 938107562 nsec, audio time 938112708 nsec, systime delta -51
Example 1 shows that the timestamp at the DMA level is close to 1ms
ahead of the actual playback time (as a side time this sort of
measurement can help define rewind safeguards). Compensating for the
DMA-link delay in example 2 helps remove the hardware buffering abut
DMA-link delay in example 2 helps remove the hardware buffering but
the information is still very jittery, with up to one sample of
error. In example 3 where the timestamps are measured with the link
wallclock, the timestamps show a monotonic behavior and a lower
......
......@@ -1611,7 +1611,6 @@ F: drivers/*/*/*s3c2410*
F: drivers/memory/samsung/*
F: drivers/soc/samsung/*
F: drivers/spi/spi-s3c*
F: sound/soc/samsung/*
F: Documentation/arm/Samsung/
F: Documentation/devicetree/bindings/arm/samsung/
F: Documentation/devicetree/bindings/sram/samsung-sram.txt
......@@ -7355,6 +7354,13 @@ F: Documentation/devicetree/bindings/i2c/max6697.txt
F: drivers/hwmon/max6697.c
F: include/linux/platform_data/max6697.h
MAX9860 MONO AUDIO VOICE CODEC DRIVER
M: Peter Rosin <peda@axentia.se>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/sound/max9860.txt
F: sound/soc/codecs/max9860.*
MAXIM MUIC CHARGER DRIVERS FOR EXYNOS BASED BOARDS
M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
L: linux-pm@vger.kernel.org
......@@ -10027,7 +10033,9 @@ S: Maintained
F: drivers/platform/x86/samsung-laptop.c
SAMSUNG AUDIO (ASoC) DRIVERS
M: Krzysztof Kozlowski <k.kozlowski@samsung.com>
M: Sangbeom Kim <sbkim73@samsung.com>
M: Sylwester Nawrocki <s.nawrocki@samsung.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
F: sound/soc/samsung/
......@@ -10856,6 +10864,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
W: http://alsa-project.org/main/index.php/ASoC
S: Supported
F: Documentation/devicetree/bindings/sound/
F: Documentation/sound/alsa/soc/
F: sound/soc/
F: include/sound/soc*
......
......@@ -887,6 +887,34 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
}
EXPORT_SYMBOL_GPL(device_get_next_child_node);
/**
* device_get_named_child_node - Return first matching named child node handle
* @dev: Device to find the named child node for.
* @childname: String to match child node name against.
*/
struct fwnode_handle *device_get_named_child_node(struct device *dev,
const char *childname)
{
struct fwnode_handle *child;
/*
* Find first matching named child node of this device.
* For ACPI this will be a data only sub-node.
*/
device_for_each_child_node(dev, child) {
if (is_of_node(child)) {
if (!of_node_cmp(to_of_node(child)->name, childname))
return child;
} else if (is_acpi_data_node(child)) {
if (acpi_data_node_match(child, childname))
return child;
}
}
return NULL;
}
EXPORT_SYMBOL_GPL(device_get_named_child_node);
/**
* fwnode_handle_put - Drop reference to a device node
* @fwnode: Pointer to the device node to drop the reference to.
......
......@@ -420,6 +420,13 @@ static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwn
container_of(fwnode, struct acpi_data_node, fwnode) : NULL;
}
static inline bool acpi_data_node_match(struct fwnode_handle *fwnode,
const char *name)
{
return is_acpi_data_node(fwnode) ?
(!strcmp(to_acpi_data_node(fwnode)->name, name)) : false;
}
static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
{
return &adev->fwnode;
......
......@@ -608,6 +608,12 @@ static inline struct acpi_data_node *to_acpi_data_node(struct fwnode_handle *fwn
return NULL;
}
static inline bool acpi_data_node_match(struct fwnode_handle *fwnode,
const char *name)
{
return false;
}
static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
{
return NULL;
......
......@@ -14,6 +14,7 @@
#define _WM_ARIZONA_CORE_H
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/mfd/arizona/pdata.h>
......@@ -148,8 +149,17 @@ struct arizona {
uint16_t dac_comp_coeff;
uint8_t dac_comp_enabled;
struct mutex dac_comp_lock;
struct blocking_notifier_head notifier;
};
static inline int arizona_call_notifiers(struct arizona *arizona,
unsigned long event,
void *data)
{
return blocking_notifier_call_chain(&arizona->notifier, event, data);
}
int arizona_clk32k_enable(struct arizona *arizona);
int arizona_clk32k_disable(struct arizona *arizona);
......
......@@ -238,13 +238,6 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
#endif
/* Default string compare functions, Allow arch asm/prom.h to override */
#if !defined(of_compat_cmp)
#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
#endif
#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
......@@ -728,6 +721,13 @@ static inline void of_property_clear_flag(struct property *p, unsigned long flag
#define of_match_node(_matches, _node) NULL
#endif /* CONFIG_OF */
/* Default string compare functions, Allow arch asm/prom.h to override */
#if !defined(of_compat_cmp)
#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
#define of_prop_cmp(s1, s2) strcmp((s1), (s2))
#define of_node_cmp(s1, s2) strcasecmp((s1), (s2))
#endif
#if defined(CONFIG_OF) && defined(CONFIG_NUMA)
extern int of_node_to_nid(struct device_node *np);
#else
......
......@@ -77,6 +77,9 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
for (child = device_get_next_child_node(dev, NULL); child; \
child = device_get_next_child_node(dev, child))
struct fwnode_handle *device_get_named_child_node(struct device *dev,
const char *childname);
void fwnode_handle_put(struct fwnode_handle *fwnode);
unsigned int device_get_child_node_count(struct device *dev);
......
......@@ -68,6 +68,7 @@ struct snd_compr_runtime {
* @ops: pointer to DSP callbacks
* @runtime: pointer to runtime structure
* @device: device pointer
* @error_work: delayed work used when closing the stream due to an error
* @direction: stream direction, playback/recording
* @metadata_set: metadata set flag, true when set
* @next_track: has userspace signal next track transition, true when set
......@@ -78,6 +79,7 @@ struct snd_compr_stream {
struct snd_compr_ops *ops;
struct snd_compr_runtime *runtime;
struct snd_compr *device;
struct delayed_work error_work;
enum snd_compr_direction direction;
bool metadata_set;
bool next_track;
......@@ -187,4 +189,7 @@ static inline void snd_compr_drain_notify(struct snd_compr_stream *stream)
wake_up(&stream->runtime->sleep);
}
int snd_compr_stop_error(struct snd_compr_stream *stream,
snd_pcm_state_t state);
#endif
/*
* linux/sound/cs35l33.h -- Platform data for CS35l33
*
* Copyright (c) 2016 Cirrus Logic Inc.
*
* 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 __CS35L33_H
#define __CS35L33_H
struct cs35l33_hg {
bool enable_hg_algo;
unsigned int mem_depth;
unsigned int release_rate;
unsigned int hd_rm;
unsigned int ldo_thld;
unsigned int ldo_path_disable;
unsigned int ldo_entry_delay;
bool vp_hg_auto;
unsigned int vp_hg;
unsigned int vp_hg_rate;
unsigned int vp_hg_va;
};
struct cs35l33_pdata {
/* Boost Controller Voltage Setting */
unsigned int boost_ctl;
/* Boost Controller Peak Current */
unsigned int boost_ipk;
/* Amplifier Drive Select */
unsigned int amp_drv_sel;
/* soft volume ramp */
unsigned int ramp_rate;
/* IMON adc scale */
unsigned int imon_adc_scale;
/* H/G algo configuration */
struct cs35l33_hg hg_config;
};
#endif /* __CS35L33_H */
......@@ -53,18 +53,19 @@ struct hdmi_codec_params {
int channels;
};
struct hdmi_codec_pdata;
struct hdmi_codec_ops {
/*
* Called when ASoC starts an audio stream setup.
* Optional
*/
int (*audio_startup)(struct device *dev);
int (*audio_startup)(struct device *dev, void *data);
/*
* Configures HDMI-encoder for audio stream.
* Mandatory
*/
int (*hw_params)(struct device *dev,
int (*hw_params)(struct device *dev, void *data,
struct hdmi_codec_daifmt *fmt,
struct hdmi_codec_params *hparms);
......@@ -72,19 +73,20 @@ struct hdmi_codec_ops {
* Shuts down the audio stream.
* Mandatory
*/
void (*audio_shutdown)(struct device *dev);
void (*audio_shutdown)(struct device *dev, void *data);
/*
* Mute/unmute HDMI audio stream.
* Optional
*/
int (*digital_mute)(struct device *dev, bool enable);
int (*digital_mute)(struct device *dev, void *data, bool enable);
/*
* Provides EDID-Like-Data from connected HDMI device.
* Optional
*/
int (*get_eld)(struct device *dev, uint8_t *buf, size_t len);
int (*get_eld)(struct device *dev, void *data,
uint8_t *buf, size_t len);
};
/* HDMI codec initalization data */
......@@ -93,6 +95,7 @@ struct hdmi_codec_pdata {
uint i2s:1;
uint spdif:1;
int max_i2s_channels;
void *data;
};
#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
......
......@@ -13,16 +13,7 @@
#define __SIMPLE_CARD_H
#include <sound/soc.h>
struct asoc_simple_dai {
const char *name;
unsigned int sysclk;
int slots;
int slot_width;
unsigned int tx_slot_mask;
unsigned int rx_slot_mask;
struct clk *clk;
};
#include <sound/simple_card_utils.h>
struct asoc_simple_card_info {
const char *name;
......
/*
* simple_card_core.h
*
* Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.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.
*/
#ifndef __SIMPLE_CARD_CORE_H
#define __SIMPLE_CARD_CORE_H
#include <sound/soc.h>
struct asoc_simple_dai {
const char *name;
unsigned int sysclk;
int slots;
int slot_width;
unsigned int tx_slot_mask;
unsigned int rx_slot_mask;
struct clk *clk;
};
int asoc_simple_card_parse_daifmt(struct device *dev,
struct device_node *node,
struct device_node *codec,
char *prefix,
unsigned int *retfmt);
int asoc_simple_card_set_dailink_name(struct device *dev,
struct snd_soc_dai_link *dai_link,
const char *fmt, ...);
int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
char *prefix);
#endif /* __SIMPLE_CARD_CORE_H */
......@@ -358,6 +358,7 @@ struct snd_soc_dapm_context;
struct regulator;
struct snd_soc_dapm_widget_list;
struct snd_soc_dapm_update;
enum snd_soc_dapm_direction;
int dapm_regulator_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
......@@ -382,6 +383,9 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget,
int num);
struct snd_soc_dapm_widget *snd_soc_dapm_new_control(
struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
struct snd_soc_dai *dai);
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);
......@@ -451,7 +455,9 @@ void dapm_mark_endpoints_dirty(struct snd_soc_card *card);
/* dapm path query */
int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
struct snd_soc_dapm_widget_list **list);
struct snd_soc_dapm_widget_list **list,
bool (*custom_stop_condition)(struct snd_soc_dapm_widget *,
enum snd_soc_dapm_direction));
struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
struct snd_kcontrol *kcontrol);
......
......@@ -179,6 +179,17 @@
.get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \
.private_value = SOC_DOUBLE_R_S_VALUE(reg_left, reg_right, xshift, \
xmin, xmax, xsign_bit, xinvert) }
#define SOC_SINGLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
SNDRV_CTL_ELEM_ACCESS_READWRITE, \
.tlv.p = (tlv_array), \
.info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
.put = snd_soc_put_volsw, \
.private_value = (unsigned long)&(struct soc_mixer_control) \
{.reg = xreg, .rreg = xreg, \
.min = xmin, .max = xmax, .platform_max = xmax, \
.sign_bit = 7,} }
#define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
......
......@@ -2,7 +2,6 @@
#
obj-$(CONFIG_SOUND) += soundcore.o
obj-$(CONFIG_SOUND_PRIME) += sound_firmware.o
obj-$(CONFIG_SOUND_PRIME) += oss/
obj-$(CONFIG_DMASOUND) += oss/
obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \
......
......@@ -67,6 +67,8 @@ struct snd_compr_file {
struct snd_compr_stream stream;
};
static void error_delayed_work(struct work_struct *work);
/*
* a note on stream states used:
* we use following states in the compressed core
......@@ -123,6 +125,9 @@ static int snd_compr_open(struct inode *inode, struct file *f)
snd_card_unref(compr->card);
return -ENOMEM;
}
INIT_DELAYED_WORK(&data->stream.error_work, error_delayed_work);
data->stream.ops = compr->ops;
data->stream.direction = dirn;
data->stream.private_data = compr->private_data;
......@@ -153,6 +158,8 @@ static int snd_compr_free(struct inode *inode, struct file *f)
struct snd_compr_file *data = f->private_data;
struct snd_compr_runtime *runtime = data->stream.runtime;
cancel_delayed_work_sync(&data->stream.error_work);
switch (runtime->state) {
case SNDRV_PCM_STATE_RUNNING:
case SNDRV_PCM_STATE_DRAINING:
......@@ -237,6 +244,15 @@ snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg)
avail = snd_compr_calc_avail(stream, &ioctl_avail);
ioctl_avail.avail = avail;
switch (stream->runtime->state) {
case SNDRV_PCM_STATE_OPEN:
return -EBADFD;
case SNDRV_PCM_STATE_XRUN:
return -EPIPE;
default:
break;
}
if (copy_to_user((__u64 __user *)arg,
&ioctl_avail, sizeof(ioctl_avail)))
return -EFAULT;
......@@ -346,11 +362,13 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf,
switch (stream->runtime->state) {
case SNDRV_PCM_STATE_OPEN:
case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_XRUN:
case SNDRV_PCM_STATE_SUSPENDED:
case SNDRV_PCM_STATE_DISCONNECTED:
retval = -EBADFD;
goto out;
case SNDRV_PCM_STATE_XRUN:
retval = -EPIPE;
goto out;
}
avail = snd_compr_get_avail(stream);
......@@ -399,10 +417,16 @@ static unsigned int snd_compr_poll(struct file *f, poll_table *wait)
stream = &data->stream;
mutex_lock(&stream->device->lock);
if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) {
switch (stream->runtime->state) {
case SNDRV_PCM_STATE_OPEN:
case SNDRV_PCM_STATE_XRUN:
retval = snd_compr_get_poll(stream) | POLLERR;
goto out;
default:
break;
}
poll_wait(f, &stream->runtime->sleep, wait);
avail = snd_compr_get_avail(stream);
......@@ -697,6 +721,45 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
return retval;
}
static void error_delayed_work(struct work_struct *work)
{
struct snd_compr_stream *stream;
stream = container_of(work, struct snd_compr_stream, error_work.work);
mutex_lock(&stream->device->lock);
stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
wake_up(&stream->runtime->sleep);
mutex_unlock(&stream->device->lock);
}
/*
* snd_compr_stop_error: Report a fatal error on a stream
* @stream: pointer to stream
* @state: state to transition the stream to
*
* Stop the stream and set its state.
*
* Should be called with compressed device lock held.
*/
int snd_compr_stop_error(struct snd_compr_stream *stream,
snd_pcm_state_t state)
{
if (stream->runtime->state == state)
return 0;
stream->runtime->state = state;
pr_debug("Changing state to: %d\n", state);
queue_delayed_work(system_power_efficient_wq, &stream->error_work, 0);
return 0;
}
EXPORT_SYMBOL_GPL(snd_compr_stop_error);
static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
{
int ret;
......
......@@ -807,6 +807,36 @@ static int snd_ctl_elem_list(struct snd_card *card,
return 0;
}
static bool validate_element_member_dimension(struct snd_ctl_elem_info *info)
{
unsigned int members;
unsigned int i;
if (info->dimen.d[0] == 0)
return true;
members = 1;
for (i = 0; i < ARRAY_SIZE(info->dimen.d); ++i) {
if (info->dimen.d[i] == 0)
break;
members *= info->dimen.d[i];
/*
* info->count should be validated in advance, to guarantee
* calculation soundness.
*/
if (members > info->count)
return false;
}
for (++i; i < ARRAY_SIZE(info->dimen.d); ++i) {
if (info->dimen.d[i] > 0)
return false;
}
return members == info->count;
}
static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
struct snd_ctl_elem_info *info)
{
......@@ -1274,6 +1304,8 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
if (info->count < 1 ||
info->count > max_value_counts[info->type])
return -EINVAL;
if (!validate_element_member_dimension(info))
return -EINVAL;
private_size = value_sizes[info->type] * info->count;
/*
......
......@@ -70,11 +70,11 @@ struct seq_oss_synth {
static int max_synth_devs;
static struct seq_oss_synth *synth_devs[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS];
static struct seq_oss_synth midi_synth_dev = {
-1, /* seq_device */
SYNTH_TYPE_MIDI, /* synth_type */
0, /* synth_subtype */
16, /* nr_voices */
"MIDI", /* name */
.seq_device = -1,
.synth_type = SYNTH_TYPE_MIDI,
.synth_subtype = 0,
.nr_voices = 16,
.name = "MIDI",
};
static DEFINE_SPINLOCK(register_lock);
......
......@@ -165,7 +165,7 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri,
snd_seq_timer_update_tick(&tmr->tick, resolution);
/* register actual time of this timer update */
do_gettimeofday(&tmr->last_update);
ktime_get_ts64(&tmr->last_update);
spin_unlock_irqrestore(&tmr->lock, flags);
......@@ -392,7 +392,7 @@ static int seq_timer_start(struct snd_seq_timer *tmr)
return -EINVAL;
snd_timer_start(tmr->timeri, tmr->ticks);
tmr->running = 1;
do_gettimeofday(&tmr->last_update);
ktime_get_ts64(&tmr->last_update);
return 0;
}
......@@ -420,7 +420,7 @@ static int seq_timer_continue(struct snd_seq_timer *tmr)
}
snd_timer_start(tmr->timeri, tmr->ticks);
tmr->running = 1;
do_gettimeofday(&tmr->last_update);
ktime_get_ts64(&tmr->last_update);
return 0;
}
......@@ -444,17 +444,12 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
spin_lock_irqsave(&tmr->lock, flags);
cur_time = tmr->cur_time;
if (tmr->running) {
struct timeval tm;
int usec;
do_gettimeofday(&tm);
usec = (int)(tm.tv_usec - tmr->last_update.tv_usec);
if (usec < 0) {
cur_time.tv_nsec += (1000000 + usec) * 1000;
cur_time.tv_sec += tm.tv_sec - tmr->last_update.tv_sec - 1;
} else {
cur_time.tv_nsec += usec * 1000;
cur_time.tv_sec += tm.tv_sec - tmr->last_update.tv_sec;
}
struct timespec64 tm;
ktime_get_ts64(&tm);
tm = timespec64_sub(tm, tmr->last_update);
cur_time.tv_nsec = tm.tv_nsec;
cur_time.tv_sec = tm.tv_sec;
snd_seq_sanity_real_time(&cur_time);
}
spin_unlock_irqrestore(&tmr->lock, flags);
......
......@@ -52,7 +52,7 @@ struct snd_seq_timer {
unsigned int skew;
unsigned int skew_base;
struct timeval last_update; /* time of last clock update, used for interpolation */
struct timespec64 last_update; /* time of last clock update, used for interpolation */
spinlock_t lock;
};
......
......@@ -353,7 +353,8 @@ static void hdmi_std_setup_channel_mapping(struct hdac_chmap *chmap,
int hdmi_slot = 0;
/* fill actual channel mappings in ALSA channel (i) order */
for (i = 0; i < ch_alloc->channels; i++) {
while (!ch_alloc->speakers[7 - hdmi_slot] && !WARN_ON(hdmi_slot >= 8))
while (!WARN_ON(hdmi_slot >= 8) &&
!ch_alloc->speakers[7 - hdmi_slot])
hdmi_slot++; /* skip zero slots */
hdmi_channel_mapping[ca][i] = (i << 4) | hdmi_slot++;
......@@ -430,6 +431,12 @@ static int to_cea_slot(int ordered_ca, unsigned char pos)
int mask = snd_hdac_chmap_to_spk_mask(pos);
int i;
/* Add sanity check to pass klockwork check.
* This should never happen.
*/
if (ordered_ca >= ARRAY_SIZE(channel_allocations))
return -1;
if (mask) {
for (i = 0; i < 8; i++) {
if (channel_allocations[ordered_ca].speakers[7 - i] == mask)
......@@ -456,7 +463,15 @@ EXPORT_SYMBOL_GPL(snd_hdac_spk_to_chmap);
/* from CEA slot to ALSA API channel position */
static int from_cea_slot(int ordered_ca, unsigned char slot)
{
int mask = channel_allocations[ordered_ca].speakers[7 - slot];
int mask;
/* Add sanity check to pass klockwork check.
* This should never happen.
*/
if (slot >= 8)
return 0;
mask = channel_allocations[ordered_ca].speakers[7 - slot];
return snd_hdac_spk_to_chmap(mask);
}
......@@ -523,7 +538,8 @@ static void hdmi_setup_fake_chmap(unsigned char *map, int ca)
int ordered_ca = get_channel_allocation_order(ca);
for (i = 0; i < 8; i++) {
if (i < channel_allocations[ordered_ca].channels)
if (ordered_ca < ARRAY_SIZE(channel_allocations) &&
i < channel_allocations[ordered_ca].channels)
map[i] = from_cea_slot(ordered_ca, hdmi_channel_mapping[ca][i] & 0x0f);
else
map[i] = 0;
......@@ -551,6 +567,12 @@ int snd_hdac_get_active_channels(int ca)
{
int ordered_ca = get_channel_allocation_order(ca);
/* Add sanity check to pass klockwork check.
* This should never happen.
*/
if (ordered_ca >= ARRAY_SIZE(channel_allocations))
ordered_ca = 0;
return channel_allocations[ordered_ca].channels;
}
EXPORT_SYMBOL_GPL(snd_hdac_get_active_channels);
......
......@@ -121,7 +121,7 @@ int snd_ak4114_create(struct snd_card *card,
__fail:
snd_ak4114_free(chip);
return err < 0 ? err : -EIO;
return err;
}
EXPORT_SYMBOL(snd_ak4114_create);
......
......@@ -110,7 +110,7 @@ int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t
__fail:
snd_ak4117_free(chip);
return err < 0 ? err : -EIO;
return err;
}
void snd_ak4117_reg_write(struct ak4117 *chip, unsigned char reg, unsigned char mask, unsigned char val)
......
......@@ -170,15 +170,4 @@ static struct isa_driver snd_ad1848_driver = {
}
};
static int __init alsa_card_ad1848_init(void)
{
return isa_register_driver(&snd_ad1848_driver, SNDRV_CARDS);
}
static void __exit alsa_card_ad1848_exit(void)
{
isa_unregister_driver(&snd_ad1848_driver);
}
module_init(alsa_card_ad1848_init);
module_exit(alsa_card_ad1848_exit);
module_isa_driver(snd_ad1848_driver, SNDRV_CARDS);
......@@ -112,15 +112,4 @@ static struct isa_driver snd_adlib_driver = {
}
};
static int __init alsa_card_adlib_init(void)
{
return isa_register_driver(&snd_adlib_driver, SNDRV_CARDS);
}
static void __exit alsa_card_adlib_exit(void)
{
isa_unregister_driver(&snd_adlib_driver);
}
module_init(alsa_card_adlib_init);
module_exit(alsa_card_adlib_exit);
module_isa_driver(snd_adlib_driver, SNDRV_CARDS);
......@@ -469,15 +469,4 @@ static struct isa_driver snd_cmi8328_driver = {
},
};
static int __init alsa_card_cmi8328_init(void)
{
return isa_register_driver(&snd_cmi8328_driver, CMI8328_MAX);
}
static void __exit alsa_card_cmi8328_exit(void)
{
isa_unregister_driver(&snd_cmi8328_driver);
}
module_init(alsa_card_cmi8328_init)
module_exit(alsa_card_cmi8328_exit)
module_isa_driver(snd_cmi8328_driver, CMI8328_MAX);
......@@ -186,15 +186,4 @@ static struct isa_driver snd_cs4231_driver = {
}
};
static int __init alsa_card_cs4231_init(void)
{
return isa_register_driver(&snd_cs4231_driver, SNDRV_CARDS);
}
static void __exit alsa_card_cs4231_exit(void)
{
isa_unregister_driver(&snd_cs4231_driver);
}
module_init(alsa_card_cs4231_init);
module_exit(alsa_card_cs4231_exit);
module_isa_driver(snd_cs4231_driver, SNDRV_CARDS);
......@@ -634,15 +634,4 @@ static struct isa_driver snd_galaxy_driver = {
}
};
static int __init alsa_card_galaxy_init(void)
{
return isa_register_driver(&snd_galaxy_driver, SNDRV_CARDS);
}
static void __exit alsa_card_galaxy_exit(void)
{
isa_unregister_driver(&snd_galaxy_driver);
}
module_init(alsa_card_galaxy_init);
module_exit(alsa_card_galaxy_exit);
module_isa_driver(snd_galaxy_driver, SNDRV_CARDS);
......@@ -229,15 +229,4 @@ static struct isa_driver snd_gusclassic_driver = {
}
};
static int __init alsa_card_gusclassic_init(void)
{
return isa_register_driver(&snd_gusclassic_driver, SNDRV_CARDS);
}
static void __exit alsa_card_gusclassic_exit(void)
{
isa_unregister_driver(&snd_gusclassic_driver);
}
module_init(alsa_card_gusclassic_init);
module_exit(alsa_card_gusclassic_exit);
module_isa_driver(snd_gusclassic_driver, SNDRV_CARDS);
......@@ -358,15 +358,4 @@ static struct isa_driver snd_gusextreme_driver = {
}
};
static int __init alsa_card_gusextreme_init(void)
{
return isa_register_driver(&snd_gusextreme_driver, SNDRV_CARDS);
}
static void __exit alsa_card_gusextreme_exit(void)
{
isa_unregister_driver(&snd_gusextreme_driver);
}
module_init(alsa_card_gusextreme_init);
module_exit(alsa_card_gusextreme_exit);
module_isa_driver(snd_gusextreme_driver, SNDRV_CARDS);
......@@ -370,15 +370,4 @@ static struct isa_driver snd_gusmax_driver = {
},
};
static int __init alsa_card_gusmax_init(void)
{
return isa_register_driver(&snd_gusmax_driver, SNDRV_CARDS);
}
static void __exit alsa_card_gusmax_exit(void)
{
isa_unregister_driver(&snd_gusmax_driver);
}
module_init(alsa_card_gusmax_init)
module_exit(alsa_card_gusmax_exit)
module_isa_driver(snd_gusmax_driver, SNDRV_CARDS);
......@@ -387,15 +387,4 @@ static struct isa_driver snd_jazz16_driver = {
},
};
static int __init alsa_card_jazz16_init(void)
{
return isa_register_driver(&snd_jazz16_driver, SNDRV_CARDS);
}
static void __exit alsa_card_jazz16_exit(void)
{
isa_unregister_driver(&snd_jazz16_driver);
}
module_init(alsa_card_jazz16_init)
module_exit(alsa_card_jazz16_exit)
module_isa_driver(snd_jazz16_driver, SNDRV_CARDS);
......@@ -251,15 +251,4 @@ static struct isa_driver snd_sb8_driver = {
},
};
static int __init alsa_card_sb8_init(void)
{
return isa_register_driver(&snd_sb8_driver, SNDRV_CARDS);
}
static void __exit alsa_card_sb8_exit(void)
{
isa_unregister_driver(&snd_sb8_driver);
}
module_init(alsa_card_sb8_init)
module_exit(alsa_card_sb8_exit)
module_isa_driver(snd_sb8_driver, SNDRV_CARDS);
......@@ -711,15 +711,4 @@ static struct isa_driver snd_sc6000_driver = {
};
static int __init alsa_card_sc6000_init(void)
{
return isa_register_driver(&snd_sc6000_driver, SNDRV_CARDS);
}
static void __exit alsa_card_sc6000_exit(void)
{
isa_unregister_driver(&snd_sc6000_driver);
}
module_init(alsa_card_sc6000_init)
module_exit(alsa_card_sc6000_exit)
module_isa_driver(snd_sc6000_driver, SNDRV_CARDS);
......@@ -254,7 +254,7 @@ static void ad_write(ad1848_info * devc, int reg, int data)
static void wait_for_calibration(ad1848_info * devc)
{
int timeout = 0;
int timeout;
/*
* Wait until the auto calibration process has finished.
......
......@@ -482,13 +482,13 @@ static struct orVals orDMA[] __initdata = {
};
static struct aedsp16_info ae_config = {
DEF_AEDSP16_IOB,
DEF_AEDSP16_IRQ,
DEF_AEDSP16_MRQ,
DEF_AEDSP16_DMA,
-1,
-1,
INIT_NONE
.base_io = DEF_AEDSP16_IOB,
.irq = DEF_AEDSP16_IRQ,
.mpu_irq = DEF_AEDSP16_MRQ,
.dma = DEF_AEDSP16_DMA,
.mss_base = -1,
.mpu_base = -1,
.init = INIT_NONE
};
/*
......
extern int mod_firmware_load(const char *fn, char **fp);
#include <linux/fs.h>
/**
* mod_firmware_load - load sound driver firmware
* @fn: filename
* @fp: return for the buffer.
*
* Load the firmware for a sound module (up to 128K) into a buffer.
* The buffer is returned in *fp. It is allocated with vmalloc so is
* virtually linear and not DMAable. The caller should free it with
* vfree when finished.
*
* The length of the buffer is returned on a successful load, the
* value zero on a failure.
*
* Caution: This API is not recommended. Firmware should be loaded via
* request_firmware.
*/
static inline int mod_firmware_load(const char *fn, char **fp)
{
loff_t size;
int err;
err = kernel_read_file_from_path((char *)fn, (void **)fp, &size,
131072, READING_FIRMWARE);
if (err < 0)
return 0;
return size;
}
......@@ -17,7 +17,7 @@
#include "sound_config.h"
static volatile int initialized, opened, tmr_running;
static volatile time_t tmr_offs, tmr_ctr;
static volatile unsigned int tmr_offs, tmr_ctr;
static volatile unsigned long ticks_offs;
static volatile int curr_tempo, curr_timebase;
static volatile unsigned long curr_ticks;
......
......@@ -19,7 +19,7 @@
#include "sound_config.h"
static volatile int opened, tmr_running;
static volatile time_t tmr_offs, tmr_ctr;
static volatile unsigned int tmr_offs, tmr_ctr;
static volatile unsigned long ticks_offs;
static volatile int curr_tempo, curr_timebase;
static volatile unsigned long curr_ticks;
......
......@@ -1615,23 +1615,23 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
int i;
struct regs_cs4382 cs_read = {0};
struct regs_cs4382 cs_def = {
0x00000001, /* Mode Control 1 */
0x00000000, /* Mode Control 2 */
0x00000084, /* Mode Control 3 */
0x00000000, /* Filter Control */
0x00000000, /* Invert Control */
0x00000024, /* Mixing Control Pair 1 */
0x00000000, /* Vol Control A1 */
0x00000000, /* Vol Control B1 */
0x00000024, /* Mixing Control Pair 2 */
0x00000000, /* Vol Control A2 */
0x00000000, /* Vol Control B2 */
0x00000024, /* Mixing Control Pair 3 */
0x00000000, /* Vol Control A3 */
0x00000000, /* Vol Control B3 */
0x00000024, /* Mixing Control Pair 4 */
0x00000000, /* Vol Control A4 */
0x00000000 /* Vol Control B4 */
.mode_control_1 = 0x00000001, /* Mode Control 1 */
.mode_control_2 = 0x00000000, /* Mode Control 2 */
.mode_control_3 = 0x00000084, /* Mode Control 3 */
.filter_control = 0x00000000, /* Filter Control */
.invert_control = 0x00000000, /* Invert Control */
.mix_control_P1 = 0x00000024, /* Mixing Control Pair 1 */
.vol_control_A1 = 0x00000000, /* Vol Control A1 */
.vol_control_B1 = 0x00000000, /* Vol Control B1 */
.mix_control_P2 = 0x00000024, /* Mixing Control Pair 2 */
.vol_control_A2 = 0x00000000, /* Vol Control A2 */
.vol_control_B2 = 0x00000000, /* Vol Control B2 */
.mix_control_P3 = 0x00000024, /* Mixing Control Pair 3 */
.vol_control_A3 = 0x00000000, /* Vol Control A3 */
.vol_control_B3 = 0x00000000, /* Vol Control B3 */
.mix_control_P4 = 0x00000024, /* Mixing Control Pair 4 */
.vol_control_A4 = 0x00000000, /* Vol Control A4 */
.vol_control_B4 = 0x00000000 /* Vol Control B4 */
};
if (hw->model == CTSB1270) {
......
......@@ -1272,11 +1272,11 @@ static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol,
chip = snd_kcontrol_chip(kcontrol);
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
uinfo->value.integer.min = ECHOGAIN_MINOUT;
uinfo->value.integer.max = ECHOGAIN_MAXOUT;
uinfo->dimen.d[0] = num_busses_out(chip);
uinfo->dimen.d[1] = num_busses_in(chip);
uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1];
return 0;
}
......@@ -1344,11 +1344,11 @@ static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol,
chip = snd_kcontrol_chip(kcontrol);
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 1;
uinfo->value.integer.min = ECHOGAIN_MINOUT;
uinfo->value.integer.max = ECHOGAIN_MAXOUT;
uinfo->dimen.d[0] = num_busses_out(chip);
uinfo->dimen.d[1] = num_pipes_out(chip);
uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1];
return 0;
}
......@@ -1728,7 +1728,6 @@ static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 96;
uinfo->value.integer.min = ECHOGAIN_MINOUT;
uinfo->value.integer.max = 0;
#ifdef ECHOCARD_HAS_VMIXER
......@@ -1738,6 +1737,7 @@ static int snd_echo_vumeters_info(struct snd_kcontrol *kcontrol,
#endif
uinfo->dimen.d[1] = 16; /* 16 channels */
uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */
uinfo->count = uinfo->dimen.d[0] * uinfo->dimen.d[1] * uinfo->dimen.d[2];
return 0;
}
......
......@@ -3584,6 +3584,12 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
bool reset;
spdif = snd_hda_spdif_out_of_nid(codec, nid);
/* Add sanity check to pass klockwork check.
* This should never happen.
*/
if (WARN_ON(spdif == NULL))
return;
curr_fmt = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_STREAM_FORMAT, 0);
reset = codec->spdif_status_reset &&
......@@ -3768,7 +3774,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
spdif = snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid);
if (mout->dig_out_nid && mout->share_spdif &&
mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
if (chs == 2 &&
if (chs == 2 && spdif != NULL &&
snd_hda_is_supported_format(codec, mout->dig_out_nid,
format) &&
!(spdif->status & IEC958_AES0_NONAUDIO)) {
......
......@@ -2492,10 +2492,6 @@ static int create_loopback_mixing_ctl(struct hda_codec *codec)
if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum))
return -ENOMEM;
spec->have_aamix_ctl = 1;
/* if no explicit aamix path is present (e.g. for Realtek codecs),
* enable aamix as default -- just for compatibility
*/
spec->aamix_mode = !has_aamix_out_paths(spec);
return 0;
}
......
......@@ -1680,6 +1680,11 @@ static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
mutex_lock(&codec->spdif_mutex);
spdif = snd_hda_spdif_out_of_nid(codec, cvt_nid);
/* Add sanity check to pass klockwork check.
* This should never happen.
*/
if (WARN_ON(spdif == NULL))
return true;
non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO);
mutex_unlock(&codec->spdif_mutex);
return non_pcm;
......
......@@ -3718,6 +3718,9 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
case 0x10ec0295:
alc_process_coef_fw(codec, coef0225);
break;
case 0x10ec0867:
alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
break;
}
codec_dbg(codec, "Headset jack set to unplugged mode.\n");
}
......@@ -3805,6 +3808,9 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
alc_process_coef_fw(codec, coef0293);
snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
break;
case 0x10ec0867:
alc_update_coefex_idx(codec, 0x57, 0x5, 0, 1<<14);
/* fallthru */
case 0x10ec0662:
snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
......@@ -3899,6 +3905,9 @@ static void alc_headset_mode_default(struct hda_codec *codec)
case 0x10ec0668:
alc_process_coef_fw(codec, coef0688);
break;
case 0x10ec0867:
alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
break;
}
codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
}
......@@ -3989,6 +3998,9 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
case 0x10ec0295:
alc_process_coef_fw(codec, coef0225);
break;
case 0x10ec0867:
alc_update_coefex_idx(codec, 0x57, 0x5, 1<<14, 0);
break;
}
codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
}
......@@ -4166,6 +4178,9 @@ static void alc_determine_headset_type(struct hda_codec *codec)
val = alc_read_coef_idx(codec, 0x46);
is_ctia = (val & 0x00f0) == 0x00f0;
break;
case 0x10ec0867:
is_ctia = true;
break;
}
codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
......@@ -6532,6 +6547,8 @@ enum {
ALC668_FIXUP_DELL_XPS13,
ALC662_FIXUP_ASUS_Nx50,
ALC668_FIXUP_ASUS_Nx51,
ALC891_FIXUP_HEADSET_MODE,
ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
};
static const struct hda_fixup alc662_fixups[] = {
......@@ -6787,6 +6804,20 @@ static const struct hda_fixup alc662_fixups[] = {
.chained = true,
.chain_id = ALC662_FIXUP_BASS_CHMAP,
},
[ALC891_FIXUP_HEADSET_MODE] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc_fixup_headset_mode,
},
[ALC891_FIXUP_DELL_MIC_NO_PRESENCE] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
{ 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
{ }
},
.chained = true,
.chain_id = ALC891_FIXUP_HEADSET_MODE
},
};
static const struct snd_pci_quirk alc662_fixup_tbl[] = {
......@@ -6903,6 +6934,11 @@ static const struct hda_model_fixup alc662_fixup_models[] = {
};
static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
SND_HDA_PIN_QUIRK(0x10ec0867, 0x1028, "Dell", ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
{0x17, 0x02211010},
{0x18, 0x01a19030},
{0x1a, 0x01813040},
{0x21, 0x01014020}),
SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
{0x14, 0x01014010},
{0x18, 0x01a19020},
......@@ -7091,7 +7127,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc882),
HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc662),
HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
HDA_CODEC_ENTRY(0x10ec0883, "ALC883", patch_alc882),
......
......@@ -965,7 +965,7 @@ static int mixart_update_monitoring(struct snd_mixart* chip, int channel)
int err;
struct mixart_msg request;
struct mixart_set_out_audio_level audio_level;
u32 resp;
u32 resp = 0;
if(chip->pipe_out_ana.status == PIPE_UNDEFINED)
return -EINVAL; /* no pipe defined */
......
......@@ -1496,7 +1496,7 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream)
f = PAGE_SIZE;
while ((size + (f >> 1) - 1) <= (f << 7) && (f << 1) > period)
f = f >> 1;
pages = (size + f - 1) / f;
pages = DIV_ROUND_UP(size, f);
data->size = size;
data->pages = pages;
snd_printdd
......
......@@ -991,6 +991,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip)
if (err < 0)
return err;
}
master_vol = NULL;
if (pm7500)
err = build_mixers(chip,
ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500),
......
......@@ -63,9 +63,6 @@ MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard.");
module_param(enable, bool, 0644);
MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");
/* Use workqueue */
static struct workqueue_struct *aica_queue;
/* Simple platform device */
static struct platform_device *pd;
static struct resource aica_memory_space[2] = {
......@@ -327,7 +324,7 @@ static void aica_period_elapsed(unsigned long timer_var)
dreamcastcard->current_period = play_period;
if (unlikely(dreamcastcard->dma_check == 0))
dreamcastcard->dma_check = 1;
queue_work(aica_queue, &(dreamcastcard->spu_dma_work));
schedule_work(&(dreamcastcard->spu_dma_work));
}
static void spu_begin_dma(struct snd_pcm_substream *substream)
......@@ -337,7 +334,7 @@ static void spu_begin_dma(struct snd_pcm_substream *substream)
runtime = substream->runtime;
dreamcastcard = substream->pcm->private_data;
/*get the queue to do the work */
queue_work(aica_queue, &(dreamcastcard->spu_dma_work));
schedule_work(&(dreamcastcard->spu_dma_work));
/* Timer may already be running */
if (unlikely(dreamcastcard->timer.data)) {
mod_timer(&dreamcastcard->timer, jiffies + 4);
......@@ -381,7 +378,7 @@ static int snd_aicapcm_pcm_close(struct snd_pcm_substream
*substream)
{
struct snd_card_aica *dreamcastcard = substream->pcm->private_data;
flush_workqueue(aica_queue);
flush_work(&(dreamcastcard->spu_dma_work));
if (dreamcastcard->timer.data)
del_timer(&dreamcastcard->timer);
kfree(dreamcastcard->channel);
......@@ -633,9 +630,6 @@ static int snd_aica_probe(struct platform_device *devptr)
if (unlikely(err < 0))
goto freedreamcast;
platform_set_drvdata(devptr, dreamcastcard);
aica_queue = create_workqueue(CARD_NAME);
if (unlikely(!aica_queue))
goto freedreamcast;
snd_printk
("ALSA Driver for Yamaha AICA Super Intelligent Sound Processor\n");
return 0;
......@@ -671,10 +665,6 @@ static int __init aica_init(void)
static void __exit aica_exit(void)
{
/* Destroy the aica kernel thread *
* being extra cautious to check if it exists*/
if (likely(aica_queue))
destroy_workqueue(aica_queue);
platform_device_unregister(pd);
platform_driver_unregister(&snd_aica_driver);
/* Kill any sound still playing and reset ARM7 to safe state */
......
......@@ -10,6 +10,7 @@ if SND_ATMEL_SOC
config SND_ATMEL_SOC_PDC
tristate
depends on HAS_DMA
default m if SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=m
default y if SND_ATMEL_SOC_SSC_PDC=y || (SND_ATMEL_SOC_SSC_PDC=m && SND_ATMEL_SOC_SSC=y)
......
......@@ -593,11 +593,6 @@ static int atmel_classd_probe(struct platform_device *pdev)
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "no memory resource\n");
return -ENXIO;
}
io_base = devm_ioremap_resource(dev, res);
if (IS_ERR(io_base)) {
ret = PTR_ERR(io_base);
......
......@@ -624,11 +624,6 @@ static int atmel_pdmic_probe(struct platform_device *pdev)
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "no memory resource\n");
return -ENXIO;
}
io_base = devm_ioremap_resource(dev, res);
if (IS_ERR(io_base)) {
ret = PTR_ERR(io_base);
......
......@@ -321,7 +321,7 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
return ret;
}
dma_params = &ssc_dma_params[dai->id][dir];
dma_params = &ssc_dma_params[pdev->id][dir];
dma_params->ssc = ssc_p->ssc;
dma_params->substream = substream;
......
......@@ -7,3 +7,12 @@ config SND_BCM2835_SOC_I2S
Say Y or M if you want to add support for codecs attached to
the BCM2835 I2S interface. You will also need
to select the audio interfaces to support below.
config SND_SOC_CYGNUS
tristate "SoC platform audio for Broadcom Cygnus chips"
depends on ARCH_BCM_CYGNUS || COMPILE_TEST
help
Say Y if you want to add support for ASoC audio on Broadcom
Cygnus chips (bcm958300, bcm958305, bcm911360)
If you don't know what to do here, say N.
\ No newline at end of file
......@@ -3,3 +3,8 @@ snd-soc-bcm2835-i2s-objs := bcm2835-i2s.o
obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o
# CYGNUS Platform Support
snd-soc-cygnus-objs := cygnus-pcm.o cygnus-ssp.o
obj-$(CONFIG_SND_SOC_CYGNUS) += snd-soc-cygnus.o
此差异已折叠。
此差异已折叠。
/*
* Copyright (C) 2014-2015 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __CYGNUS_SSP_H__
#define __CYGNUS_SSP_H__
#define CYGNUS_TDM_DAI_MAX_SLOTS 16
#define CYGNUS_MAX_PLAYBACK_PORTS 4
#define CYGNUS_MAX_CAPTURE_PORTS 3
#define CYGNUS_MAX_I2S_PORTS 3
#define CYGNUS_MAX_PORTS CYGNUS_MAX_PLAYBACK_PORTS
#define CYGNUS_AUIDO_MAX_NUM_CLKS 3
#define CYGNUS_SSP_FRAMEBITS_DIV 1
#define CYGNUS_SSPMODE_I2S 0
#define CYGNUS_SSPMODE_TDM 1
#define CYGNUS_SSPMODE_UNKNOWN -1
#define CYGNUS_SSP_CLKSRC_PLL 0
/* Max string length of our dt property names */
#define PROP_LEN_MAX 40
struct ringbuf_regs {
unsigned rdaddr;
unsigned wraddr;
unsigned baseaddr;
unsigned endaddr;
unsigned fmark; /* freemark for play, fullmark for caputure */
unsigned period_bytes;
unsigned buf_size;
};
#define RINGBUF_REG_PLAYBACK(num) ((struct ringbuf_regs) { \
.rdaddr = SRC_RBUF_ ##num## _RDADDR_OFFSET, \
.wraddr = SRC_RBUF_ ##num## _WRADDR_OFFSET, \
.baseaddr = SRC_RBUF_ ##num## _BASEADDR_OFFSET, \
.endaddr = SRC_RBUF_ ##num## _ENDADDR_OFFSET, \
.fmark = SRC_RBUF_ ##num## _FREE_MARK_OFFSET, \
.period_bytes = 0, \
.buf_size = 0, \
})
#define RINGBUF_REG_CAPTURE(num) ((struct ringbuf_regs) { \
.rdaddr = DST_RBUF_ ##num## _RDADDR_OFFSET, \
.wraddr = DST_RBUF_ ##num## _WRADDR_OFFSET, \
.baseaddr = DST_RBUF_ ##num## _BASEADDR_OFFSET, \
.endaddr = DST_RBUF_ ##num## _ENDADDR_OFFSET, \
.fmark = DST_RBUF_ ##num## _FULL_MARK_OFFSET, \
.period_bytes = 0, \
.buf_size = 0, \
})
enum cygnus_audio_port_type {
PORT_TDM,
PORT_SPDIF,
};
struct cygnus_ssp_regs {
u32 i2s_stream_cfg;
u32 i2s_cfg;
u32 i2s_cap_stream_cfg;
u32 i2s_cap_cfg;
u32 i2s_mclk_cfg;
u32 bf_destch_ctrl;
u32 bf_destch_cfg;
u32 bf_sourcech_ctrl;
u32 bf_sourcech_cfg;
u32 bf_sourcech_grp;
};
struct cygnus_track_clk {
bool cap_en;
bool play_en;
bool cap_clk_en;
bool play_clk_en;
};
struct cygnus_aio_port {
int portnum;
int mode;
bool is_slave;
int streams_on; /* will be 0 if both capture and play are off */
int fsync_width;
int port_type;
u32 mclk;
u32 lrclk;
u32 bit_per_frame;
u32 pll_clk_num;
struct cygnus_audio *cygaud;
struct cygnus_ssp_regs regs;
struct ringbuf_regs play_rb_regs;
struct ringbuf_regs capture_rb_regs;
struct snd_pcm_substream *play_stream;
struct snd_pcm_substream *capture_stream;
struct cygnus_track_clk clk_trace;
};
struct cygnus_audio {
struct cygnus_aio_port portinfo[CYGNUS_MAX_PORTS];
int irq_num;
void __iomem *audio;
struct device *dev;
void __iomem *i2s_in;
struct clk *audio_clk[CYGNUS_AUIDO_MAX_NUM_CLKS];
int active_ports;
unsigned long vco_rate;
};
extern int cygnus_ssp_get_mode(struct snd_soc_dai *cpu_dai);
extern int cygnus_ssp_add_pll_tweak_controls(struct snd_soc_pcm_runtime *rtd);
extern int cygnus_ssp_set_custom_fsync_width(struct snd_soc_dai *cpu_dai,
int len);
extern int cygnus_soc_platform_register(struct device *dev,
struct cygnus_audio *cygaud);
extern int cygnus_soc_platform_unregister(struct device *dev);
extern int cygnus_ssp_set_custom_fsync_width(struct snd_soc_dai *cpu_dai,
int len);
#endif
......@@ -32,6 +32,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_ADAU1977_SPI if SPI_MASTER
select SND_SOC_ADAU1977_I2C if I2C
select SND_SOC_ADAU1701 if I2C
select SND_SOC_ADAU7002
select SND_SOC_ADS117X
select SND_SOC_AK4104 if SPI_MASTER
select SND_SOC_AK4535 if I2C
......@@ -46,6 +47,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_BT_SCO
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
select SND_SOC_CS35L32 if I2C
select SND_SOC_CS35L33 if I2C
select SND_SOC_CS42L51_I2C if I2C
select SND_SOC_CS42L52 if I2C && INPUT
select SND_SOC_CS42L56 if I2C && INPUT
......@@ -57,6 +59,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS42XX8_I2C if I2C
select SND_SOC_CS4349 if I2C
select SND_SOC_CS47L24 if MFD_CS47L24
select SND_SOC_CS53L30 if I2C
select SND_SOC_CX20442 if TTY
select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
select SND_SOC_DA7213 if I2C
......@@ -84,6 +87,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX98925 if I2C
select SND_SOC_MAX98926 if I2C
select SND_SOC_MAX9850 if I2C
select SND_SOC_MAX9860 if I2C
select SND_SOC_MAX9768 if I2C
select SND_SOC_MAX9877 if I2C
select SND_SOC_MC13783 if MFD_MC13XXX
......@@ -269,8 +273,12 @@ config SND_SOC_AD1980
config SND_SOC_AD73311
tristate
config SND_SOC_ADAU_UTILS
tristate
config SND_SOC_ADAU1373
tristate
select SND_SOC_ADAU_UTILS
config SND_SOC_ADAU1701
tristate "Analog Devices ADAU1701 CODEC"
......@@ -280,6 +288,7 @@ config SND_SOC_ADAU1701
config SND_SOC_ADAU17X1
tristate
select SND_SOC_SIGMADSP_REGMAP
select SND_SOC_ADAU_UTILS
config SND_SOC_ADAU1761
tristate
......@@ -322,6 +331,9 @@ config SND_SOC_ADAU1977_I2C
select SND_SOC_ADAU1977
select REGMAP_I2C
config SND_SOC_ADAU7002
tristate "Analog Devices ADAU7002 Stereo PDM-to-I2S/TDM Converter"
config SND_SOC_ADAV80X
tristate
......@@ -371,7 +383,7 @@ config SND_SOC_ALC5632
tristate
config SND_SOC_BT_SCO
tristate
tristate "Dummy BT SCO codec driver"
config SND_SOC_CQ0093VC
tristate
......@@ -380,6 +392,10 @@ config SND_SOC_CS35L32
tristate "Cirrus Logic CS35L32 CODEC"
depends on I2C
config SND_SOC_CS35L33
tristate "Cirrus Logic CS35L33 CODEC"
depends on I2C
config SND_SOC_CS42L51
tristate
......@@ -450,6 +466,11 @@ config SND_SOC_CS4349
config SND_SOC_CS47L24
tristate
# Cirrus Logic Quad-Channel ADC
config SND_SOC_CS53L30
tristate "Cirrus Logic CS53L30 CODEC"
depends on I2C
config SND_SOC_CX20442
tristate
depends on TTY
......@@ -536,6 +557,10 @@ config SND_SOC_MAX98357A
config SND_SOC_MAX98371
tristate
config SND_SOC_MAX98504
tristate "Maxim MAX98504 speaker amplifier"
depends on I2C
config SND_SOC_MAX9867
tristate
......@@ -548,6 +573,11 @@ config SND_SOC_MAX98926
config SND_SOC_MAX9850
tristate
config SND_SOC_MAX9860
tristate "Maxim MAX9860 Mono Audio Voice Codec"
depends on I2C
select REGMAP_I2C
config SND_SOC_PCM1681
tristate "Texas Instruments PCM1681 CODEC"
depends on I2C
......@@ -644,6 +674,9 @@ config SND_SOC_RT298
config SND_SOC_RT5514
tristate
config SND_SOC_RT5514_SPI
tristate
config SND_SOC_RT5616
tristate "Realtek RT5616 CODEC"
depends on I2C
......@@ -969,7 +1002,8 @@ config SND_SOC_WM8983
tristate
config SND_SOC_WM8985
tristate
tristate "Wolfson Microelectronics WM8985 and WM8758 codec driver"
depends on SND_SOC_I2C_AND_SPI
config SND_SOC_WM8988
tristate
......
......@@ -7,6 +7,7 @@ snd-soc-ad193x-spi-objs := ad193x-spi.o
snd-soc-ad193x-i2c-objs := ad193x-i2c.o
snd-soc-ad1980-objs := ad1980.o
snd-soc-ad73311-objs := ad73311.o
snd-soc-adau-utils-objs := adau-utils.o
snd-soc-adau1373-objs := adau1373.o
snd-soc-adau1701-objs := adau1701.o
snd-soc-adau17x1-objs := adau17x1.o
......@@ -19,6 +20,7 @@ snd-soc-adau1781-spi-objs := adau1781-spi.o
snd-soc-adau1977-objs := adau1977.o
snd-soc-adau1977-spi-objs := adau1977-spi.o
snd-soc-adau1977-i2c-objs := adau1977-i2c.o
snd-soc-adau7002-objs := adau7002.o
snd-soc-adav80x-objs := adav80x.o
snd-soc-adav801-objs := adav801.o
snd-soc-adav803-objs := adav803.o
......@@ -35,6 +37,7 @@ snd-soc-arizona-objs := arizona.o
snd-soc-bt-sco-objs := bt-sco.o
snd-soc-cq93vc-objs := cq93vc.o
snd-soc-cs35l32-objs := cs35l32.o
snd-soc-cs35l33-objs := cs35l33.o
snd-soc-cs42l51-objs := cs42l51.o
snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o
snd-soc-cs42l52-objs := cs42l52.o
......@@ -49,6 +52,7 @@ snd-soc-cs42xx8-objs := cs42xx8.o
snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
snd-soc-cs4349-objs := cs4349.o
snd-soc-cs47l24-objs := cs47l24.o
snd-soc-cs53l30-objs := cs53l30.o
snd-soc-cx20442-objs := cx20442.o
snd-soc-da7210-objs := da7210.o
snd-soc-da7213-objs := da7213.o
......@@ -79,6 +83,7 @@ snd-soc-max9867-objs := max9867.o
snd-soc-max98925-objs := max98925.o
snd-soc-max98926-objs := max98926.o
snd-soc-max9850-objs := max9850.o
snd-soc-max9860-objs := max9860.o
snd-soc-mc13783-objs := mc13783.o
snd-soc-ml26124-objs := ml26124.o
snd-soc-nau8825-objs := nau8825.o
......@@ -100,6 +105,7 @@ snd-soc-rl6347a-objs := rl6347a.o
snd-soc-rt286-objs := rt286.o
snd-soc-rt298-objs := rt298.o
snd-soc-rt5514-objs := rt5514.o
snd-soc-rt5514-spi-objs := rt5514-spi.o
snd-soc-rt5616-objs := rt5616.o
snd-soc-rt5631-objs := rt5631.o
snd-soc-rt5640-objs := rt5640.o
......@@ -208,6 +214,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
# Amp
snd-soc-max9877-objs := max9877.o
snd-soc-max98504-objs := max98504.o
snd-soc-tpa6130a2-objs := tpa6130a2.o
snd-soc-tas2552-objs := tas2552.o
......@@ -220,6 +227,7 @@ obj-$(CONFIG_SND_SOC_AD193X_SPI) += snd-soc-ad193x-spi.o
obj-$(CONFIG_SND_SOC_AD193X_I2C) += snd-soc-ad193x-i2c.o
obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
obj-$(CONFIG_SND_SOC_ADAU_UTILS) += snd-soc-adau-utils.o
obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o
obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o
obj-$(CONFIG_SND_SOC_ADAU17X1) += snd-soc-adau17x1.o
......@@ -232,6 +240,7 @@ obj-$(CONFIG_SND_SOC_ADAU1781_SPI) += snd-soc-adau1781-spi.o
obj-$(CONFIG_SND_SOC_ADAU1977) += snd-soc-adau1977.o
obj-$(CONFIG_SND_SOC_ADAU1977_SPI) += snd-soc-adau1977-spi.o
obj-$(CONFIG_SND_SOC_ADAU1977_I2C) += snd-soc-adau1977-i2c.o
obj-$(CONFIG_SND_SOC_ADAU7002) += snd-soc-adau7002.o
obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o
obj-$(CONFIG_SND_SOC_ADAV801) += snd-soc-adav801.o
obj-$(CONFIG_SND_SOC_ADAV803) += snd-soc-adav803.o
......@@ -250,6 +259,7 @@ obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.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_CS35L32) += snd-soc-cs35l32.o
obj-$(CONFIG_SND_SOC_CS35L33) += snd-soc-cs35l33.o
obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o
obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
......@@ -264,6 +274,7 @@ obj-$(CONFIG_SND_SOC_CS42XX8) += snd-soc-cs42xx8.o
obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.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
obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
......@@ -293,6 +304,7 @@ obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o
obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o
obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
......@@ -314,6 +326,7 @@ obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o
obj-$(CONFIG_SND_SOC_RT5514) += snd-soc-rt5514.o
obj-$(CONFIG_SND_SOC_RT5514_SPI) += snd-soc-rt5514-spi.o
obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o
obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
......@@ -419,4 +432,5 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
# Amp
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o
obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
/*
* Shared helper functions for devices from the ADAU family
*
* Copyright 2011-2016 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*
* Licensed under the GPL-2 or later.
*/
#include <linux/gcd.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include "adau-utils.h"
int adau_calc_pll_cfg(unsigned int freq_in, unsigned int freq_out,
uint8_t regs[5])
{
unsigned int r, n, m, i, j;
unsigned int div;
if (!freq_out) {
r = 0;
n = 0;
m = 0;
div = 0;
} else {
if (freq_out % freq_in != 0) {
div = DIV_ROUND_UP(freq_in, 13500000);
freq_in /= div;
r = freq_out / freq_in;
i = freq_out % freq_in;
j = gcd(i, freq_in);
n = i / j;
m = freq_in / j;
div--;
} else {
r = freq_out / freq_in;
n = 0;
m = 0;
div = 0;
}
if (n > 0xffff || m > 0xffff || div > 3 || r > 8 || r < 2)
return -EINVAL;
}
regs[0] = m >> 8;
regs[1] = m & 0xff;
regs[2] = n >> 8;
regs[3] = n & 0xff;
regs[4] = (r << 3) | (div << 1);
if (m != 0)
regs[4] |= 1; /* Fractional mode */
return 0;
}
EXPORT_SYMBOL_GPL(adau_calc_pll_cfg);
MODULE_DESCRIPTION("ASoC ADAU audio CODECs shared helper functions");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_LICENSE("GPL v2");
#ifndef SOUND_SOC_CODECS_ADAU_PLL_H
#define SOUND_SOC_CODECS_ADAU_PLL_H
int adau_calc_pll_cfg(unsigned int freq_in, unsigned int freq_out,
uint8_t regs[5]);
#endif
此差异已折叠。
......@@ -31,7 +31,7 @@ static int adau1761_i2c_probe(struct i2c_client *client,
static int adau1761_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
adau17x1_remove(&client->dev);
return 0;
}
......
......@@ -48,7 +48,7 @@ static int adau1761_spi_probe(struct spi_device *spi)
static int adau1761_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
adau17x1_remove(&spi->dev);
return 0;
}
......
......@@ -31,7 +31,7 @@ static int adau1781_i2c_probe(struct i2c_client *client,
static int adau1781_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
adau17x1_remove(&client->dev);
return 0;
}
......
......@@ -48,7 +48,7 @@ static int adau1781_spi_probe(struct spi_device *spi)
static int adau1781_spi_remove(struct spi_device *spi)
{
snd_soc_unregister_codec(&spi->dev);
adau17x1_remove(&spi->dev);
return 0;
}
......
此差异已折叠。
......@@ -22,13 +22,18 @@ enum adau17x1_pll_src {
};
enum adau17x1_clk_src {
/* Automatically configure PLL based on the sample rate */
ADAU17X1_CLK_SRC_PLL_AUTO,
ADAU17X1_CLK_SRC_MCLK,
ADAU17X1_CLK_SRC_PLL,
};
struct clk;
struct adau {
unsigned int sysclk;
unsigned int pll_freq;
struct clk *mclk;
enum adau17x1_clk_src clk_src;
enum adau17x1_type type;
......@@ -52,6 +57,7 @@ int adau17x1_add_routes(struct snd_soc_codec *codec);
int adau17x1_probe(struct device *dev, struct regmap *regmap,
enum adau17x1_type type, void (*switch_mode)(struct device *dev),
const char *firmware_name);
void adau17x1_remove(struct device *dev);
int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec,
enum adau17x1_micbias_voltage micbias);
bool adau17x1_readable_register(struct device *dev, unsigned int reg);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
文件模式从 100755 更改为 100644
文件模式从 100755 更改为 100644
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册