ASoC: Updates for v3.20
More updates for v3.20: - Lots of refactoring from Lars-Peter Clausen, moving drivers to more data driven initialization and rationalizing a lot of DAPM usage. - Much improved handling of CDCLK clocks on Samsung I2S controllers. - Lots of driver specific cleanups and feature improvements. - CODEC support for TI PCM514x and TLV320AIC3104 devices. - Board support for Tegra systems with Realtek RT5677. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJU0ok8AAoJECTWi3JdVIfQ3ccH/2zb+b477H4GNhUw5AEzdHtC L7CI+5Q9VOGJQmZTjayRdUcPUHx4sTpYdQVTI56Q6CJk0OFljKNJcRrbzPqNgJ46 yOrMTIpNvzFEv46f7rX2uKfvAFOVRAA2f+gl34AMLXqxL5aydbZZBtoe2jP9lL8z fIZ/s7qXHn3xnvxqNwOz3pnu6wFDrxbG34lXZaTaFQOueZ3fsthWLsz0xtO6a7aI J9tA+wejd9qf+D3i6svsi+MhB6OehYMh9Fbm+ODj6NMWZGCIA3SJ/PD+gbCg318+ Xo0FNOyiw0fSAeBcHrEcfoaWBJrswxXjXaNbrIXc1/0gTj8AOJHCRus3w0OQU+Q= =Yw2l -----END PGP SIGNATURE----- Merge tag 'asoc-v3.20-2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next ASoC: Updates for v3.20 More updates for v3.20: - Lots of refactoring from Lars-Peter Clausen, moving drivers to more data driven initialization and rationalizing a lot of DAPM usage. - Much improved handling of CDCLK clocks on Samsung I2S controllers. - Lots of driver specific cleanups and feature improvements. - CODEC support for TI PCM514x and TLV320AIC3104 devices. - Board support for Tegra systems with Realtek RT5677. Conflicts: sound/soc/intel/sst-mfld-platform-pcm.c
This commit is contained in:
commit
a3ae255e37
|
@ -0,0 +1,18 @@
|
|||
Bindings for I2S controller built into xtfpga Xtensa bitstreams.
|
||||
|
||||
Required properties:
|
||||
- compatible: shall be "cdns,xtfpga-i2s".
|
||||
- reg: memory region (address and length) with device registers.
|
||||
- interrupts: interrupt for the device.
|
||||
- clocks: phandle to the clk used as master clock. I2S bus clock
|
||||
is derived from it.
|
||||
|
||||
Examples:
|
||||
|
||||
i2s0: xtfpga-i2s@0d080000 {
|
||||
#sound-dai-cells = <0>;
|
||||
compatible = "cdns,xtfpga-i2s";
|
||||
reg = <0x0d080000 0x40>;
|
||||
interrupts = <2 1>;
|
||||
clocks = <&cdce706 4>;
|
||||
};
|
|
@ -0,0 +1,31 @@
|
|||
DesignWare I2S controller
|
||||
|
||||
Required properties:
|
||||
- compatible : Must be "snps,designware-i2s"
|
||||
- reg : Must contain the I2S core's registers location and length
|
||||
- clocks : Pairs of phandle and specifier referencing the controller's
|
||||
clocks. The controller expects one clock: the clock used as the sampling
|
||||
rate reference clock sample.
|
||||
- clock-names : "i2sclk" for the sample rate reference clock.
|
||||
- dmas: Pairs of phandle and specifier for the DMA channels that are used by
|
||||
the core. The core expects one or two dma channels: one for transmit and
|
||||
one for receive.
|
||||
- dma-names : "tx" for the transmit channel, "rx" for the receive channel.
|
||||
|
||||
For more details on the 'dma', 'dma-names', 'clock' and 'clock-names'
|
||||
properties please check:
|
||||
* resource-names.txt
|
||||
* clock/clock-bindings.txt
|
||||
* dma/dma.txt
|
||||
|
||||
Example:
|
||||
|
||||
soc_i2s: i2s@7ff90000 {
|
||||
compatible = "snps,designware-i2s";
|
||||
reg = <0x0 0x7ff90000 0x0 0x1000>;
|
||||
clocks = <&scpi_i2sclk 0>;
|
||||
clock-names = "i2sclk";
|
||||
#sound-dai-cells = <0>;
|
||||
dmas = <&dma0 5>;
|
||||
dma-names = "tx";
|
||||
};
|
|
@ -0,0 +1,67 @@
|
|||
NVIDIA Tegra audio complex, with RT5677 CODEC
|
||||
|
||||
Required properties:
|
||||
- compatible : "nvidia,tegra-audio-rt5677"
|
||||
- clocks : Must contain an entry for each entry in clock-names.
|
||||
See ../clocks/clock-bindings.txt for details.
|
||||
- clock-names : Must include the following entries:
|
||||
- pll_a
|
||||
- pll_a_out0
|
||||
- mclk (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
|
||||
- nvidia,model : The user-visible name of this sound complex.
|
||||
- nvidia,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 RT5677's pins (as documented in its binding), and the jacks
|
||||
on the board:
|
||||
|
||||
* Headphone
|
||||
* Speaker
|
||||
* Headset Mic
|
||||
* Internal Mic 1
|
||||
* Internal Mic 2
|
||||
|
||||
- nvidia,i2s-controller : The phandle of the Tegra I2S controller that's
|
||||
connected to the CODEC.
|
||||
- nvidia,audio-codec : The phandle of the RT5677 audio codec. This binding
|
||||
assumes that AIF1 on the CODEC is connected to Tegra.
|
||||
|
||||
Optional properties:
|
||||
- nvidia,hp-det-gpios : The GPIO that detects headphones are plugged in
|
||||
- nvidia,hp-en-gpios : The GPIO that enables headphone amplifier
|
||||
- nvidia,mic-present-gpios: The GPIO that mic jack is plugged in
|
||||
- nvidia,dmic-clk-en-gpios : The GPIO that gates DMIC clock signal
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "nvidia,tegra-audio-rt5677-ryu",
|
||||
"nvidia,tegra-audio-rt5677";
|
||||
nvidia,model = "NVIDIA Tegra Ryu";
|
||||
|
||||
nvidia,audio-routing =
|
||||
"Headphone", "LOUT2",
|
||||
"Headphone", "LOUT1",
|
||||
"Headset Mic", "MICBIAS1",
|
||||
"IN1P", "Headset Mic",
|
||||
"IN1N", "Headset Mic",
|
||||
"DMIC L1", "Internal Mic 1",
|
||||
"DMIC R1", "Internal Mic 1",
|
||||
"DMIC L2", "Internal Mic 2",
|
||||
"DMIC R2", "Internal Mic 2",
|
||||
"Speaker", "PDM1L",
|
||||
"Speaker", "PDM1R";
|
||||
|
||||
nvidia,i2s-controller = <&tegra_i2s1>;
|
||||
nvidia,audio-codec = <&rt5677>;
|
||||
|
||||
nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(R, 7) GPIO_ACTIVE_HIGH>;
|
||||
nvidia,mic-present-gpios = <&gpio TEGRA_GPIO(O, 5) GPIO_ACTIVE_LOW>;
|
||||
nvidia,hp-en-gpios = <&rt5677 1 GPIO_ACTIVE_HIGH>;
|
||||
nvidia,dmic-clk-en-gpios = <&rt5677 2 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
clocks = <&tegra_car TEGRA124_CLK_PLL_A>,
|
||||
<&tegra_car TEGRA124_CLK_PLL_A_OUT0>,
|
||||
<&tegra_car TEGRA124_CLK_EXTERN1>;
|
||||
clock-names = "pll_a", "pll_a_out0", "mclk";
|
||||
};
|
|
@ -17,9 +17,16 @@ Required properties:
|
|||
Optional properties:
|
||||
|
||||
- clocks : A clock specifier for the clock connected as SCLK. If this
|
||||
is absent the device will be configured to clock from BCLK.
|
||||
is absent the device will be configured to clock from BCLK. If pll-in
|
||||
and pll-out are specified in addition to a clock, the device is
|
||||
configured to accept clock input on a specified gpio pin.
|
||||
|
||||
Example:
|
||||
- pll-in, pll-out : gpio pins used to connect the pll using <1>
|
||||
through <6>. The device will be configured for clock input on the
|
||||
given pll-in pin and PLL output on the given pll-out pin. An
|
||||
external connection from the pll-out pin to the SCLK pin is assumed.
|
||||
|
||||
Examples:
|
||||
|
||||
pcm5122: pcm5122@4c {
|
||||
compatible = "ti,pcm5122";
|
||||
|
@ -29,3 +36,17 @@ Example:
|
|||
DVDD-supply = <®_1v8>;
|
||||
CPVDD-supply = <®_3v3>;
|
||||
};
|
||||
|
||||
|
||||
pcm5142: pcm5142@4c {
|
||||
compatible = "ti,pcm5142";
|
||||
reg = <0x4c>;
|
||||
|
||||
AVDD-supply = <®_3v3_analog>;
|
||||
DVDD-supply = <®_1v8>;
|
||||
CPVDD-supply = <®_3v3>;
|
||||
|
||||
clocks = <&sck>;
|
||||
pll-in = <3>;
|
||||
pll-out = <6>;
|
||||
};
|
||||
|
|
|
@ -33,6 +33,25 @@ Required SoC Specific Properties:
|
|||
"iis" is the i2s bus clock and i2s_opclk0, i2s_opclk1 are sources of the root
|
||||
clk. i2s0 has internal mux to select the source of root clk and i2s1 and i2s2
|
||||
doesn't have any such mux.
|
||||
- #clock-cells: should be 1, this property must be present if the I2S device
|
||||
is a clock provider in terms of the common clock bindings, described in
|
||||
../clock/clock-bindings.txt.
|
||||
- clock-output-names: from the common clock bindings, names of the CDCLK
|
||||
I2S output clocks, suggested values are "i2s_cdclk0", "i2s_cdclk1",
|
||||
"i2s_cdclk3" for the I2S0, I2S1, I2S2 devices recpectively.
|
||||
|
||||
There are following clocks available at the I2S device nodes:
|
||||
CLK_I2S_CDCLK - the CDCLK (CODECLKO) gate clock,
|
||||
CLK_I2S_RCLK_PSR - the RCLK prescaler divider clock (corresponding to the
|
||||
IISPSR register),
|
||||
CLK_I2S_RCLK_SRC - the RCLKSRC mux clock (corresponding to RCLKSRC bit in
|
||||
IISMOD register).
|
||||
|
||||
Refer to the SoC datasheet for availability of the above clocks.
|
||||
The CLK_I2S_RCLK_PSR and CLK_I2S_RCLK_SRC clocks are usually only available
|
||||
in the IIS Multi Audio Interface (I2S0).
|
||||
Note: Old DTs may not have the #clock-cells, clock-output-names properties
|
||||
and then not use the I2S node as a clock supplier.
|
||||
|
||||
Optional SoC Specific Properties:
|
||||
|
||||
|
@ -41,6 +60,7 @@ Optional SoC Specific Properties:
|
|||
- pinctrl-0: Should specify pin control groups used for this controller.
|
||||
- pinctrl-names: Should contain only one value - "default".
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
i2s0: i2s@03830000 {
|
||||
|
@ -54,6 +74,8 @@ i2s0: i2s@03830000 {
|
|||
<&clock_audss EXYNOS_I2S_BUS>,
|
||||
<&clock_audss EXYNOS_SCLK_I2S>;
|
||||
clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
|
||||
#clock-cells;
|
||||
clock-output-names = "i2s_cdclk0";
|
||||
samsung,idma-addr = <0x03000000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2s0_bus>;
|
||||
|
|
|
@ -75,6 +75,11 @@ Optional CPU/CODEC subnodes properties:
|
|||
it can be specified via "clocks" if system has
|
||||
clock node (= common clock), or "system-clock-frequency"
|
||||
(if system doens't support common clock)
|
||||
If a clock is specified, it is
|
||||
enabled with clk_prepare_enable()
|
||||
in dai startup() and disabled with
|
||||
clk_disable_unprepare() in dai
|
||||
shutdown().
|
||||
|
||||
Example 1 - single DAI link:
|
||||
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
STA32X audio CODEC
|
||||
|
||||
The driver for this device only supports I2C.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: "st,sta32x"
|
||||
- reg: the I2C address of the device for I2C
|
||||
- reset-gpios: a GPIO spec for the reset pin. If specified, it will be
|
||||
deasserted before communication to the codec starts.
|
||||
|
||||
- power-down-gpios: a GPIO spec for the power down pin. If specified,
|
||||
it will be deasserted before communication to the codec
|
||||
starts.
|
||||
|
||||
- Vdda-supply: regulator spec, providing 3.3V
|
||||
- Vdd3-supply: regulator spec, providing 3.3V
|
||||
- Vcc-supply: regulator spec, providing 5V - 26V
|
||||
|
||||
Optional properties:
|
||||
|
||||
- st,output-conf: number, Selects the output configuration:
|
||||
0: 2-channel (full-bridge) power, 2-channel data-out
|
||||
1: 2 (half-bridge). 1 (full-bridge) on-board power
|
||||
2: 2 Channel (Full-Bridge) Power, 1 Channel FFX
|
||||
3: 1 Channel Mono-Parallel
|
||||
If parameter is missing, mode 0 will be enabled.
|
||||
This property has to be specified as '/bits/ 8' value.
|
||||
|
||||
- st,ch1-output-mapping: Channel 1 output mapping
|
||||
- st,ch2-output-mapping: Channel 2 output mapping
|
||||
- st,ch3-output-mapping: Channel 3 output mapping
|
||||
0: Channel 1
|
||||
1: Channel 2
|
||||
2: Channel 3
|
||||
If parameter is missing, channel 1 is chosen.
|
||||
This properties have to be specified as '/bits/ 8' values.
|
||||
|
||||
- st,thermal-warning-recover:
|
||||
If present, thermal warning recovery is enabled.
|
||||
|
||||
- st,thermal-warning-adjustment:
|
||||
If present, thermal warning adjustment is enabled.
|
||||
|
||||
- st,fault-detect-recovery:
|
||||
If present, then fault recovery will be enabled.
|
||||
|
||||
- st,drop-compensation-ns: number
|
||||
Only required for "st,ffx-power-output-mode" ==
|
||||
"variable-drop-compensation".
|
||||
Specifies the drop compensation in nanoseconds.
|
||||
The value must be in the range of 0..300, and only
|
||||
multiples of 20 are allowed. Default is 140ns.
|
||||
|
||||
- st,max-power-use-mpcc:
|
||||
If present, then MPCC bits are used for MPC coefficients,
|
||||
otherwise standard MPC coefficients are used.
|
||||
|
||||
- st,max-power-corr:
|
||||
If present, power bridge correction for THD reduction near maximum
|
||||
power output is enabled.
|
||||
|
||||
- st,am-reduction-mode:
|
||||
If present, FFX mode runs in AM reduction mode, otherwise normal
|
||||
FFX mode is used.
|
||||
|
||||
- st,odd-pwm-speed-mode:
|
||||
If present, PWM speed mode run on odd speed mode (341.3 kHz) on all
|
||||
channels. If not present, normal PWM spped mode (384 kHz) will be used.
|
||||
|
||||
- st,invalid-input-detect-mute:
|
||||
If present, automatic invalid input detect mute is enabled.
|
||||
|
||||
Example:
|
||||
|
||||
codec: sta32x@38 {
|
||||
compatible = "st,sta32x";
|
||||
reg = <0x1c>;
|
||||
reset-gpios = <&gpio1 19 0>;
|
||||
power-down-gpios = <&gpio1 16 0>;
|
||||
st,output-conf = /bits/ 8 <0x3>; // set output to 2-channel
|
||||
// (full-bridge) power,
|
||||
// 2-channel data-out
|
||||
st,ch1-output-mapping = /bits/ 8 <0>; // set channel 1 output ch 1
|
||||
st,ch2-output-mapping = /bits/ 8 <0>; // set channel 2 output ch 1
|
||||
st,ch3-output-mapping = /bits/ 8 <0>; // set channel 3 output ch 1
|
||||
st,max-power-correction; // enables power bridge
|
||||
// correction for THD reduction
|
||||
// near maximum power output
|
||||
st,invalid-input-detect-mute; // mute if no valid digital
|
||||
// audio signal is provided.
|
||||
};
|
|
@ -9,6 +9,7 @@ Required properties:
|
|||
"ti,tlv320aic33" - TLV320AIC33
|
||||
"ti,tlv320aic3007" - TLV320AIC3007
|
||||
"ti,tlv320aic3106" - TLV320AIC3106
|
||||
"ti,tlv320aic3104" - TLV320AIC3104
|
||||
|
||||
|
||||
- reg - <int> - I2C slave address
|
||||
|
@ -18,6 +19,7 @@ Optional properties:
|
|||
|
||||
- gpio-reset - gpio pin number used for codec reset
|
||||
- ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality
|
||||
- Not supported on tlv320aic3104
|
||||
- ai3x-micbias-vg - MicBias Voltage required.
|
||||
1 - MICBIAS output is powered to 2.0V,
|
||||
2 - MICBIAS output is powered to 2.5V,
|
||||
|
@ -36,7 +38,13 @@ CODEC output pins:
|
|||
* HPLCOM
|
||||
* HPRCOM
|
||||
|
||||
CODEC input pins:
|
||||
CODEC input pins for TLV320AIC3104:
|
||||
* MIC2L
|
||||
* MIC2R
|
||||
* LINE1L
|
||||
* LINE1R
|
||||
|
||||
CODEC input pins for other compatible codecs:
|
||||
* MIC3L
|
||||
* MIC3R
|
||||
* LINE1L
|
||||
|
|
|
@ -13,6 +13,11 @@ Required properties:
|
|||
- interrupt-parent: The parent interrupt controller
|
||||
- interrupts: Interrupt number for /INT pin from the 227e
|
||||
|
||||
Optional properies:
|
||||
- ti,micbias: Intended MICBIAS voltage (datasheet section 9.6.7).
|
||||
Select 0/1/2/3/4/5/6/7 to specify MACBIAS voltage
|
||||
2.1V/2.2V/2.3V/2.4V/2.5V/2.6V/2.7V/2.8V
|
||||
Default value is "1" (2.2V).
|
||||
|
||||
Examples:
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ WM8904 audio CODEC
|
|||
This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
- compatible: "wlf,wm8904"
|
||||
- compatible: "wlf,wm8904" or "wlf,wm8912"
|
||||
- reg: the I2C address of the device.
|
||||
- clock-names: "mclk"
|
||||
- clocks: reference to
|
||||
|
|
11
MAINTAINERS
11
MAINTAINERS
|
@ -4953,6 +4953,16 @@ F: Documentation/input/multi-touch-protocol.txt
|
|||
F: drivers/input/input-mt.c
|
||||
K: \b(ABS|SYN)_MT_
|
||||
|
||||
INTEL ASoC BDW/HSW DRIVERS
|
||||
M: Jie Yang <yang.jie@linux.intel.com>
|
||||
L: alsa-devel@alsa-project.org
|
||||
S: Supported
|
||||
F: sound/soc/intel/sst-haswell*
|
||||
F: sound/soc/intel/sst-dsp*
|
||||
F: sound/soc/intel/sst-firmware.c
|
||||
F: sound/soc/intel/broadwell.c
|
||||
F: sound/soc/intel/haswell.c
|
||||
|
||||
INTEL C600 SERIES SAS CONTROLLER DRIVER
|
||||
M: Intel SCU Linux support <intel-linux-scu@intel.com>
|
||||
M: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
|
||||
|
@ -10659,6 +10669,7 @@ M: Max Filippov <jcmvbkbc@gmail.com>
|
|||
L: linux-xtensa@linux-xtensa.org
|
||||
S: Maintained
|
||||
F: drivers/spi/spi-xtensa-xtfpga.c
|
||||
F: sound/soc/xtensa/xtfpga-i2s.c
|
||||
|
||||
YAM DRIVER FOR AX.25
|
||||
M: Jean-Paul Roubelat <jpr@f6fbb.org>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _DT_BINDINGS_SAMSUNG_I2S_H
|
||||
#define _DT_BINDINGS_SAMSUNG_I2S_H
|
||||
|
||||
#define CLK_I2S_CDCLK 0
|
||||
#define CLK_I2S_RCLK_SRC 1
|
||||
#define CLK_I2S_RCLK_PSR 2
|
||||
|
||||
#endif /* _DT_BINDINGS_SAMSUNG_I2S_H */
|
|
@ -273,6 +273,12 @@ struct snd_pcm_hw_constraint_list {
|
|||
unsigned int mask;
|
||||
};
|
||||
|
||||
struct snd_pcm_hw_constraint_ranges {
|
||||
unsigned int count;
|
||||
const struct snd_interval *ranges;
|
||||
unsigned int mask;
|
||||
};
|
||||
|
||||
struct snd_pcm_hwptr_log;
|
||||
|
||||
struct snd_pcm_runtime {
|
||||
|
@ -907,6 +913,8 @@ void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
|
|||
const struct snd_interval *b, struct snd_interval *c);
|
||||
int snd_interval_list(struct snd_interval *i, unsigned int count,
|
||||
const unsigned int *list, unsigned int mask);
|
||||
int snd_interval_ranges(struct snd_interval *i, unsigned int count,
|
||||
const struct snd_interval *list, unsigned int mask);
|
||||
int snd_interval_ratnum(struct snd_interval *i,
|
||||
unsigned int rats_count, struct snd_ratnum *rats,
|
||||
unsigned int *nump, unsigned int *denp);
|
||||
|
@ -931,6 +939,10 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
|
|||
unsigned int cond,
|
||||
snd_pcm_hw_param_t var,
|
||||
const struct snd_pcm_hw_constraint_list *l);
|
||||
int snd_pcm_hw_constraint_ranges(struct snd_pcm_runtime *runtime,
|
||||
unsigned int cond,
|
||||
snd_pcm_hw_param_t var,
|
||||
const struct snd_pcm_hw_constraint_ranges *r);
|
||||
int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime,
|
||||
unsigned int cond,
|
||||
snd_pcm_hw_param_t var,
|
||||
|
|
|
@ -55,6 +55,7 @@ struct rsnd_ssi_platform_info {
|
|||
struct rsnd_src_platform_info {
|
||||
u32 convert_rate; /* sampling rate convert */
|
||||
int dma_id; /* for Gen2 SCU */
|
||||
int irq;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -37,6 +37,9 @@ struct rt5677_platform_data {
|
|||
OFF, GPIO4, GPIO5 and GPIO6 respectively */
|
||||
unsigned int jd2_gpio;
|
||||
unsigned int jd3_gpio;
|
||||
|
||||
/* Set MICBIAS1 VDD 1v8 or 3v3 */
|
||||
bool micbias1_vdd_3v3;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@ struct asoc_simple_dai {
|
|||
unsigned int sysclk;
|
||||
int slots;
|
||||
int slot_width;
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
struct asoc_simple_card_info {
|
||||
|
|
|
@ -405,7 +405,7 @@ int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_context *dapm,
|
|||
struct snd_soc_dapm_update *update);
|
||||
|
||||
/* dapm sys fs - used by the core */
|
||||
int snd_soc_dapm_sys_add(struct device *dev);
|
||||
extern struct attribute *soc_dapm_dev_attrs[];
|
||||
void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm,
|
||||
struct dentry *parent);
|
||||
|
||||
|
@ -525,7 +525,6 @@ struct snd_soc_dapm_widget {
|
|||
enum snd_soc_dapm_type id;
|
||||
const char *name; /* widget name */
|
||||
const char *sname; /* stream name */
|
||||
struct snd_soc_codec *codec;
|
||||
struct list_head list;
|
||||
struct snd_soc_dapm_context *dapm;
|
||||
|
||||
|
|
|
@ -429,6 +429,9 @@ bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd);
|
|||
void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream);
|
||||
void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
|
||||
|
||||
int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
|
||||
unsigned int dai_fmt);
|
||||
|
||||
/* Utility functions to get clock rates from various things */
|
||||
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
|
||||
int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
|
||||
|
@ -498,6 +501,7 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg,
|
|||
unsigned int mask, unsigned int value);
|
||||
|
||||
#ifdef CONFIG_SND_SOC_AC97_BUS
|
||||
struct snd_ac97 *snd_soc_alloc_ac97_codec(struct snd_soc_codec *codec);
|
||||
struct snd_ac97 *snd_soc_new_ac97_codec(struct snd_soc_codec *codec);
|
||||
void snd_soc_free_ac97_codec(struct snd_ac97 *ac97);
|
||||
|
||||
|
|
|
@ -24,12 +24,20 @@
|
|||
#define STA32X_THERMAL_RECOVERY_ENABLE 2
|
||||
|
||||
struct sta32x_platform_data {
|
||||
int output_conf;
|
||||
int ch1_output_mapping;
|
||||
int ch2_output_mapping;
|
||||
int ch3_output_mapping;
|
||||
int thermal_conf;
|
||||
u8 output_conf;
|
||||
u8 ch1_output_mapping;
|
||||
u8 ch2_output_mapping;
|
||||
u8 ch3_output_mapping;
|
||||
int needs_esd_watchdog;
|
||||
u8 drop_compensation_ns;
|
||||
unsigned int thermal_warning_recovery:1;
|
||||
unsigned int thermal_warning_adjustment:1;
|
||||
unsigned int fault_detect_recovery:1;
|
||||
unsigned int max_power_use_mpcc:1;
|
||||
unsigned int max_power_correction:1;
|
||||
unsigned int am_reduction_mode:1;
|
||||
unsigned int odd_pwm_speed_mode:1;
|
||||
unsigned int invalid_input_detect_mute:1;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_SND__STA32X_H */
|
||||
|
|
|
@ -1015,6 +1015,60 @@ int snd_interval_list(struct snd_interval *i, unsigned int count,
|
|||
|
||||
EXPORT_SYMBOL(snd_interval_list);
|
||||
|
||||
/**
|
||||
* snd_interval_ranges - refine the interval value from the list of ranges
|
||||
* @i: the interval value to refine
|
||||
* @count: the number of elements in the list of ranges
|
||||
* @ranges: the ranges list
|
||||
* @mask: the bit-mask to evaluate
|
||||
*
|
||||
* Refines the interval value from the list of ranges.
|
||||
* When mask is non-zero, only the elements corresponding to bit 1 are
|
||||
* evaluated.
|
||||
*
|
||||
* Return: Positive if the value is changed, zero if it's not changed, or a
|
||||
* negative error code.
|
||||
*/
|
||||
int snd_interval_ranges(struct snd_interval *i, unsigned int count,
|
||||
const struct snd_interval *ranges, unsigned int mask)
|
||||
{
|
||||
unsigned int k;
|
||||
struct snd_interval range_union;
|
||||
struct snd_interval range;
|
||||
|
||||
if (!count) {
|
||||
snd_interval_none(i);
|
||||
return -EINVAL;
|
||||
}
|
||||
snd_interval_any(&range_union);
|
||||
range_union.min = UINT_MAX;
|
||||
range_union.max = 0;
|
||||
for (k = 0; k < count; k++) {
|
||||
if (mask && !(mask & (1 << k)))
|
||||
continue;
|
||||
snd_interval_copy(&range, &ranges[k]);
|
||||
if (snd_interval_refine(&range, i) < 0)
|
||||
continue;
|
||||
if (snd_interval_empty(&range))
|
||||
continue;
|
||||
|
||||
if (range.min < range_union.min) {
|
||||
range_union.min = range.min;
|
||||
range_union.openmin = 1;
|
||||
}
|
||||
if (range.min == range_union.min && !range.openmin)
|
||||
range_union.openmin = 0;
|
||||
if (range.max > range_union.max) {
|
||||
range_union.max = range.max;
|
||||
range_union.openmax = 1;
|
||||
}
|
||||
if (range.max == range_union.max && !range.openmax)
|
||||
range_union.openmax = 0;
|
||||
}
|
||||
return snd_interval_refine(i, &range_union);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_interval_ranges);
|
||||
|
||||
static int snd_interval_step(struct snd_interval *i, unsigned int step)
|
||||
{
|
||||
unsigned int n;
|
||||
|
@ -1221,6 +1275,37 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
|
|||
|
||||
EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
|
||||
|
||||
static int snd_pcm_hw_rule_ranges(struct snd_pcm_hw_params *params,
|
||||
struct snd_pcm_hw_rule *rule)
|
||||
{
|
||||
struct snd_pcm_hw_constraint_ranges *r = rule->private;
|
||||
return snd_interval_ranges(hw_param_interval(params, rule->var),
|
||||
r->count, r->ranges, r->mask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* snd_pcm_hw_constraint_ranges - apply list of range constraints to a parameter
|
||||
* @runtime: PCM runtime instance
|
||||
* @cond: condition bits
|
||||
* @var: hw_params variable to apply the list of range constraints
|
||||
* @r: ranges
|
||||
*
|
||||
* Apply the list of range constraints to an interval parameter.
|
||||
*
|
||||
* Return: Zero if successful, or a negative error code on failure.
|
||||
*/
|
||||
int snd_pcm_hw_constraint_ranges(struct snd_pcm_runtime *runtime,
|
||||
unsigned int cond,
|
||||
snd_pcm_hw_param_t var,
|
||||
const struct snd_pcm_hw_constraint_ranges *r)
|
||||
{
|
||||
return snd_pcm_hw_rule_add(runtime, cond, var,
|
||||
snd_pcm_hw_rule_ranges, (void *)r,
|
||||
var, -1);
|
||||
}
|
||||
EXPORT_SYMBOL(snd_pcm_hw_constraint_ranges);
|
||||
|
||||
static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
|
||||
struct snd_pcm_hw_rule *rule)
|
||||
{
|
||||
|
|
|
@ -55,6 +55,7 @@ source "sound/soc/spear/Kconfig"
|
|||
source "sound/soc/tegra/Kconfig"
|
||||
source "sound/soc/txx9/Kconfig"
|
||||
source "sound/soc/ux500/Kconfig"
|
||||
source "sound/soc/xtensa/Kconfig"
|
||||
|
||||
# Supported codecs
|
||||
source "sound/soc/codecs/Kconfig"
|
||||
|
|
|
@ -36,3 +36,4 @@ obj-$(CONFIG_SND_SOC) += spear/
|
|||
obj-$(CONFIG_SND_SOC) += tegra/
|
||||
obj-$(CONFIG_SND_SOC) += txx9/
|
||||
obj-$(CONFIG_SND_SOC) += ux500/
|
||||
obj-$(CONFIG_SND_SOC) += xtensa/
|
||||
|
|
|
@ -45,7 +45,7 @@ config SND_ATMEL_SOC_WM8904
|
|||
|
||||
config SND_AT91_SOC_SAM9X5_WM8731
|
||||
tristate "SoC Audio support for WM8731-based at91sam9x5 board"
|
||||
depends on ATMEL_SSC && SND_ATMEL_SOC && SOC_AT91SAM9X5
|
||||
depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC
|
||||
select SND_ATMEL_SOC_SSC
|
||||
select SND_ATMEL_SOC_DMA
|
||||
select SND_SOC_WM8731
|
||||
|
|
|
@ -105,13 +105,11 @@ static int atmel_pcm_configure_dma(struct snd_pcm_substream *substream,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
slave_config->dst_addr = ssc->phybase + SSC_THR;
|
||||
slave_config->dst_maxburst = 1;
|
||||
} else {
|
||||
slave_config->src_addr = ssc->phybase + SSC_RHR;
|
||||
slave_config->src_maxburst = 1;
|
||||
}
|
||||
slave_config->dst_addr = ssc->phybase + SSC_THR;
|
||||
slave_config->dst_maxburst = 1;
|
||||
|
||||
slave_config->src_addr = ssc->phybase + SSC_RHR;
|
||||
slave_config->src_maxburst = 1;
|
||||
|
||||
prtd->dma_intr_handler = atmel_pcm_dma_irq;
|
||||
|
||||
|
|
|
@ -204,6 +204,13 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
|
|||
pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
|
||||
ssc_readl(ssc_p->ssc->regs, SR));
|
||||
|
||||
/* Enable PMC peripheral clock for this SSC */
|
||||
pr_debug("atmel_ssc_dai: Starting clock\n");
|
||||
clk_enable(ssc_p->ssc->clk);
|
||||
|
||||
/* Reset the SSC to keep it at a clean status */
|
||||
ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
dir = 0;
|
||||
dir_mask = SSC_DIR_MASK_PLAYBACK;
|
||||
|
@ -250,11 +257,6 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
|
|||
dma_params = ssc_p->dma_params[dir];
|
||||
|
||||
if (dma_params != NULL) {
|
||||
ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
|
||||
pr_debug("atmel_ssc_shutdown: %s disabled SSC_SR=0x%08x\n",
|
||||
(dir ? "receive" : "transmit"),
|
||||
ssc_readl(ssc_p->ssc->regs, SR));
|
||||
|
||||
dma_params->ssc = NULL;
|
||||
dma_params->substream = NULL;
|
||||
ssc_p->dma_params[dir] = NULL;
|
||||
|
@ -266,10 +268,6 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
|
|||
ssc_p->dir_mask &= ~dir_mask;
|
||||
if (!ssc_p->dir_mask) {
|
||||
if (ssc_p->initialized) {
|
||||
/* Shutdown the SSC clock. */
|
||||
pr_debug("atmel_ssc_dai: Stopping clock\n");
|
||||
clk_disable(ssc_p->ssc->clk);
|
||||
|
||||
free_irq(ssc_p->ssc->irq, ssc_p);
|
||||
ssc_p->initialized = 0;
|
||||
}
|
||||
|
@ -280,6 +278,10 @@ static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
|
|||
ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
|
||||
}
|
||||
spin_unlock_irq(&ssc_p->lock);
|
||||
|
||||
/* Shutdown the SSC clock. */
|
||||
pr_debug("atmel_ssc_dai: Stopping clock\n");
|
||||
clk_disable(ssc_p->ssc->clk);
|
||||
}
|
||||
|
||||
|
||||
|
@ -348,7 +350,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
struct atmel_pcm_dma_params *dma_params;
|
||||
int dir, channels, bits;
|
||||
u32 tfmr, rfmr, tcmr, rcmr;
|
||||
int start_event;
|
||||
int ret;
|
||||
int fslen, fslen_ext;
|
||||
|
||||
|
@ -451,25 +452,10 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
|
||||
/*
|
||||
* I2S format, CODEC supplies BCLK and LRC clocks.
|
||||
*
|
||||
* The SSC transmit clock is obtained from the BCLK signal on
|
||||
* on the TK line, and the SSC receive clock is
|
||||
* generated from the transmit clock.
|
||||
*
|
||||
* For single channel data, one sample is transferred
|
||||
* on the falling edge of the LRC clock.
|
||||
* For two channel data, one sample is
|
||||
* transferred on both edges of the LRC clock.
|
||||
*/
|
||||
start_event = ((channels == 1)
|
||||
? SSC_START_FALLING_RF
|
||||
: SSC_START_EDGE_RF);
|
||||
|
||||
/* I2S format, CODEC supplies BCLK and LRC clocks. */
|
||||
rcmr = SSC_BF(RCMR_PERIOD, 0)
|
||||
| SSC_BF(RCMR_STTDLY, START_DELAY)
|
||||
| SSC_BF(RCMR_START, start_event)
|
||||
| SSC_BF(RCMR_START, SSC_START_FALLING_RF)
|
||||
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
|
||||
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
|
||||
| SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
|
||||
|
@ -478,14 +464,14 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
|
||||
| SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
|
||||
| SSC_BF(RFMR_FSLEN, 0)
|
||||
| SSC_BF(RFMR_DATNB, 0)
|
||||
| SSC_BF(RFMR_DATNB, (channels - 1))
|
||||
| SSC_BIT(RFMR_MSBF)
|
||||
| SSC_BF(RFMR_LOOP, 0)
|
||||
| SSC_BF(RFMR_DATLEN, (bits - 1));
|
||||
|
||||
tcmr = SSC_BF(TCMR_PERIOD, 0)
|
||||
| SSC_BF(TCMR_STTDLY, START_DELAY)
|
||||
| SSC_BF(TCMR_START, start_event)
|
||||
| SSC_BF(TCMR_START, SSC_START_FALLING_RF)
|
||||
| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
|
||||
| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
|
||||
| SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
|
||||
|
@ -495,7 +481,55 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
| SSC_BF(TFMR_FSDEN, 0)
|
||||
| SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
|
||||
| SSC_BF(TFMR_FSLEN, 0)
|
||||
| SSC_BF(TFMR_DATNB, 0)
|
||||
| SSC_BF(TFMR_DATNB, (channels - 1))
|
||||
| SSC_BIT(TFMR_MSBF)
|
||||
| SSC_BF(TFMR_DATDEF, 0)
|
||||
| SSC_BF(TFMR_DATLEN, (bits - 1));
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFS:
|
||||
/* I2S format, CODEC supplies BCLK, SSC supplies LRCLK. */
|
||||
if (bits > 16 && !ssc->pdata->has_fslen_ext) {
|
||||
dev_err(dai->dev,
|
||||
"sample size %d is too large for SSC device\n",
|
||||
bits);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fslen_ext = (bits - 1) / 16;
|
||||
fslen = (bits - 1) % 16;
|
||||
|
||||
rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
|
||||
| SSC_BF(RCMR_STTDLY, START_DELAY)
|
||||
| SSC_BF(RCMR_START, SSC_START_FALLING_RF)
|
||||
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
|
||||
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
|
||||
| SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
|
||||
SSC_CKS_PIN : SSC_CKS_CLOCK);
|
||||
|
||||
rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext)
|
||||
| SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
|
||||
| SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
|
||||
| SSC_BF(RFMR_FSLEN, fslen)
|
||||
| SSC_BF(RFMR_DATNB, (channels - 1))
|
||||
| SSC_BIT(RFMR_MSBF)
|
||||
| SSC_BF(RFMR_LOOP, 0)
|
||||
| SSC_BF(RFMR_DATLEN, (bits - 1));
|
||||
|
||||
tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
|
||||
| SSC_BF(TCMR_STTDLY, START_DELAY)
|
||||
| SSC_BF(TCMR_START, SSC_START_FALLING_RF)
|
||||
| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
|
||||
| SSC_BF(TCMR_CKO, SSC_CKO_NONE)
|
||||
| SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
|
||||
SSC_CKS_CLOCK : SSC_CKS_PIN);
|
||||
|
||||
tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext)
|
||||
| SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_NEGATIVE)
|
||||
| SSC_BF(TFMR_FSDEN, 0)
|
||||
| SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
|
||||
| SSC_BF(TFMR_FSLEN, fslen)
|
||||
| SSC_BF(TFMR_DATNB, (channels - 1))
|
||||
| SSC_BIT(TFMR_MSBF)
|
||||
| SSC_BF(TFMR_DATDEF, 0)
|
||||
| SSC_BF(TFMR_DATLEN, (bits - 1));
|
||||
|
@ -512,7 +546,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
|
||||
| SSC_BF(RCMR_STTDLY, 1)
|
||||
| SSC_BF(RCMR_START, SSC_START_RISING_RF)
|
||||
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
|
||||
| SSC_BF(RCMR_CKI, SSC_CKI_FALLING)
|
||||
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
|
||||
| SSC_BF(RCMR_CKS, SSC_CKS_DIV);
|
||||
|
||||
|
@ -527,7 +561,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
|
||||
| SSC_BF(TCMR_STTDLY, 1)
|
||||
| SSC_BF(TCMR_START, SSC_START_RISING_RF)
|
||||
| SSC_BF(TCMR_CKI, SSC_CKI_RISING)
|
||||
| SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
|
||||
| SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
|
||||
| SSC_BF(TCMR_CKS, SSC_CKS_DIV);
|
||||
|
||||
|
@ -545,10 +579,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
/*
|
||||
* DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks.
|
||||
*
|
||||
* The SSC transmit clock is obtained from the BCLK signal on
|
||||
* on the TK line, and the SSC receive clock is
|
||||
* generated from the transmit clock.
|
||||
*
|
||||
* Data is transferred on first BCLK after LRC pulse rising
|
||||
* edge.If stereo, the right channel data is contiguous with
|
||||
* the left channel data.
|
||||
|
@ -556,7 +586,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
rcmr = SSC_BF(RCMR_PERIOD, 0)
|
||||
| SSC_BF(RCMR_STTDLY, START_DELAY)
|
||||
| SSC_BF(RCMR_START, SSC_START_RISING_RF)
|
||||
| SSC_BF(RCMR_CKI, SSC_CKI_RISING)
|
||||
| SSC_BF(RCMR_CKI, SSC_CKI_FALLING)
|
||||
| SSC_BF(RCMR_CKO, SSC_CKO_NONE)
|
||||
| SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
|
||||
SSC_CKS_PIN : SSC_CKS_CLOCK);
|
||||
|
@ -597,23 +627,17 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
|
|||
rcmr, rfmr, tcmr, tfmr);
|
||||
|
||||
if (!ssc_p->initialized) {
|
||||
if (!ssc_p->ssc->pdata->use_dma) {
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
|
||||
|
||||
/* Enable PMC peripheral clock for this SSC */
|
||||
pr_debug("atmel_ssc_dai: Starting clock\n");
|
||||
clk_enable(ssc_p->ssc->clk);
|
||||
|
||||
/* Reset the SSC and its PDC registers */
|
||||
ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
|
||||
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
|
||||
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
|
||||
ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
|
||||
}
|
||||
|
||||
ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0,
|
||||
ssc_p->name, ssc_p);
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include <sound/soc.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#include "../codecs/wm8731.h"
|
||||
#include "atmel-pcm.h"
|
||||
|
@ -64,33 +63,6 @@
|
|||
|
||||
static struct clk *mclk;
|
||||
|
||||
static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
int ret;
|
||||
|
||||
/* set codec DAI configuration */
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set cpu DAI configuration */
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_ops at91sam9g20ek_ops = {
|
||||
.hw_params = at91sam9g20ek_hw_params,
|
||||
};
|
||||
|
||||
static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card,
|
||||
struct snd_soc_dapm_context *dapm,
|
||||
enum snd_soc_bias_level level)
|
||||
|
@ -173,7 +145,8 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = {
|
|||
.init = at91sam9g20ek_wm8731_init,
|
||||
.platform_name = "at91rm9200_ssc.0",
|
||||
.codec_name = "wm8731.0-001b",
|
||||
.ops = &at91sam9g20ek_ops,
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
};
|
||||
|
||||
static struct snd_soc_card snd_soc_at91sam9g20ek = {
|
||||
|
|
|
@ -91,27 +91,12 @@ static int db1200_i2s_startup(struct snd_pcm_substream *substream)
|
|||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
int ret;
|
||||
|
||||
/* WM8731 has its own 12MHz crystal */
|
||||
snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
|
||||
12000000, SND_SOC_CLOCK_IN);
|
||||
|
||||
/* codec is bitclock and lrclk master */
|
||||
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_LEFT_J |
|
||||
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_ops db1200_i2s_wm8731_ops = {
|
||||
|
@ -125,6 +110,8 @@ static struct snd_soc_dai_link db1200_i2s_dai = {
|
|||
.cpu_dai_name = "au1xpsc_i2s.1",
|
||||
.platform_name = "au1xpsc-pcm.1",
|
||||
.codec_name = "wm8731.0-001b",
|
||||
.dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM,
|
||||
.ops = &db1200_i2s_wm8731_ops,
|
||||
};
|
||||
|
||||
|
|
|
@ -315,11 +315,6 @@ static struct snd_pcm_ops au1xpsc_pcm_ops = {
|
|||
.pointer = au1xpsc_pcm_pointer,
|
||||
};
|
||||
|
||||
static void au1xpsc_pcm_free_dma_buffers(struct snd_pcm *pcm)
|
||||
{
|
||||
snd_pcm_lib_preallocate_free_for_all(pcm);
|
||||
}
|
||||
|
||||
static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_card *card = rtd->card->snd_card;
|
||||
|
@ -335,7 +330,6 @@ static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
|||
static struct snd_soc_platform_driver au1xpsc_soc_platform = {
|
||||
.ops = &au1xpsc_pcm_ops,
|
||||
.pcm_new = au1xpsc_pcm_new,
|
||||
.pcm_free = au1xpsc_pcm_free_dma_buffers,
|
||||
};
|
||||
|
||||
static int au1xpsc_pcm_drvprobe(struct platform_device *pdev)
|
||||
|
|
|
@ -287,11 +287,6 @@ static struct snd_pcm_ops alchemy_pcm_ops = {
|
|||
.pointer = alchemy_pcm_pointer,
|
||||
};
|
||||
|
||||
static void alchemy_pcm_free_dma_buffers(struct snd_pcm *pcm)
|
||||
{
|
||||
snd_pcm_lib_preallocate_free_for_all(pcm);
|
||||
}
|
||||
|
||||
static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_pcm *pcm = rtd->pcm;
|
||||
|
@ -305,7 +300,6 @@ static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
|||
static struct snd_soc_platform_driver alchemy_pcm_soc_platform = {
|
||||
.ops = &alchemy_pcm_ops,
|
||||
.pcm_new = alchemy_pcm_new,
|
||||
.pcm_free = alchemy_pcm_free_dma_buffers,
|
||||
};
|
||||
|
||||
static int alchemy_pcm_drvprobe(struct platform_device *pdev)
|
||||
|
|
|
@ -386,7 +386,7 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol,
|
|||
static int pm860x_rsync_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
/*
|
||||
* In order to avoid current on the load, mute power-on and power-off
|
||||
|
@ -403,7 +403,7 @@ static int pm860x_rsync_event(struct snd_soc_dapm_widget *w,
|
|||
static int pm860x_dac_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
unsigned int dac = 0;
|
||||
int data;
|
||||
|
||||
|
|
|
@ -525,7 +525,7 @@ config SND_SOC_RT5677
|
|||
|
||||
config SND_SOC_RT5677_SPI
|
||||
tristate
|
||||
default SND_SOC_RT5677
|
||||
default SND_SOC_RT5677 && SPI
|
||||
|
||||
#Freescale sgtl5000 codec
|
||||
config SND_SOC_SGTL5000
|
||||
|
@ -580,7 +580,9 @@ config SND_SOC_SSM4567
|
|||
depends on I2C
|
||||
|
||||
config SND_SOC_STA32X
|
||||
tristate
|
||||
tristate "STA326, STA328 and STA329 speaker amplifier"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
|
||||
config SND_SOC_STA350
|
||||
tristate "STA350 speaker amplifier"
|
||||
|
|
|
@ -333,8 +333,8 @@ static int ad193x_codec_probe(struct snd_soc_codec *codec)
|
|||
regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0);
|
||||
/* de-emphasis: 48kHz, powedown dac */
|
||||
regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A);
|
||||
/* powerdown dac, dac in tdm mode */
|
||||
regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x41);
|
||||
/* dac in tdm mode */
|
||||
regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x40);
|
||||
/* high-pass filter enable */
|
||||
regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3);
|
||||
/* sata delay=1, adc aux mode */
|
||||
|
|
|
@ -163,7 +163,7 @@ static const struct snd_kcontrol_new ak4671_snd_controls[] = {
|
|||
static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
|
|
@ -55,18 +55,20 @@ static inline int alc5623_reset(struct snd_soc_codec *codec)
|
|||
static int amp_mixer_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
/* to power-on/off class-d amp generators/speaker */
|
||||
/* need to write to 'index-46h' register : */
|
||||
/* so write index num (here 0x46) to reg 0x6a */
|
||||
/* and then 0xffff/0 to reg 0x6c */
|
||||
snd_soc_write(w->codec, ALC5623_HID_CTRL_INDEX, 0x46);
|
||||
snd_soc_write(codec, ALC5623_HID_CTRL_INDEX, 0x46);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0xFFFF);
|
||||
snd_soc_write(codec, ALC5623_HID_CTRL_DATA, 0xFFFF);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0);
|
||||
snd_soc_write(codec, ALC5623_HID_CTRL_DATA, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,18 +116,20 @@ static inline int alc5632_reset(struct regmap *map)
|
|||
static int amp_mixer_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
/* to power-on/off class-d amp generators/speaker */
|
||||
/* need to write to 'index-46h' register : */
|
||||
/* so write index num (here 0x46) to reg 0x6a */
|
||||
/* and then 0xffff/0 to reg 0x6c */
|
||||
snd_soc_write(w->codec, ALC5632_HID_CTRL_INDEX, 0x46);
|
||||
snd_soc_write(codec, ALC5632_HID_CTRL_INDEX, 0x46);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0xFFFF);
|
||||
snd_soc_write(codec, ALC5632_HID_CTRL_DATA, 0xFFFF);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0);
|
||||
snd_soc_write(codec, ALC5632_HID_CTRL_DATA, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1066,7 +1068,7 @@ static int alc5632_probe(struct snd_soc_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
|
||||
static const struct snd_soc_codec_driver soc_codec_device_alc5632 = {
|
||||
.probe = alc5632_probe,
|
||||
.resume = alc5632_resume,
|
||||
.set_bias_level = alc5632_set_bias_level,
|
||||
|
@ -1080,7 +1082,7 @@ static struct snd_soc_codec_driver soc_codec_device_alc5632 = {
|
|||
.num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes),
|
||||
};
|
||||
|
||||
static struct regmap_config alc5632_regmap = {
|
||||
static const struct regmap_config alc5632_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 16,
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ static int arizona_spk_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
bool manual_ena = false;
|
||||
|
@ -692,7 +692,8 @@ static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
|
|||
int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int reg;
|
||||
|
||||
if (w->shift % 2)
|
||||
|
@ -705,25 +706,25 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
|
|||
priv->in_pending++;
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
|
||||
snd_soc_update_bits(codec, reg, ARIZONA_IN1L_MUTE, 0);
|
||||
|
||||
/* If this is the last input pending then allow VU */
|
||||
priv->in_pending--;
|
||||
if (priv->in_pending == 0) {
|
||||
msleep(1);
|
||||
arizona_in_set_vu(w->codec, 1);
|
||||
arizona_in_set_vu(codec, 1);
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
snd_soc_update_bits(w->codec, reg,
|
||||
snd_soc_update_bits(codec, reg,
|
||||
ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
|
||||
ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* Disable volume updates if no inputs are enabled */
|
||||
reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
|
||||
reg = snd_soc_read(codec, ARIZONA_INPUT_ENABLES);
|
||||
if (reg == 0)
|
||||
arizona_in_set_vu(w->codec, 0);
|
||||
arizona_in_set_vu(codec, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -734,7 +735,25 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
switch (w->shift) {
|
||||
case ARIZONA_OUT1L_ENA_SHIFT:
|
||||
case ARIZONA_OUT1R_ENA_SHIFT:
|
||||
case ARIZONA_OUT2L_ENA_SHIFT:
|
||||
case ARIZONA_OUT2R_ENA_SHIFT:
|
||||
case ARIZONA_OUT3L_ENA_SHIFT:
|
||||
case ARIZONA_OUT3R_ENA_SHIFT:
|
||||
priv->out_up_pending++;
|
||||
priv->out_up_delay += 17;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
switch (w->shift) {
|
||||
case ARIZONA_OUT1L_ENA_SHIFT:
|
||||
|
@ -743,13 +762,50 @@ int arizona_out_ev(struct snd_soc_dapm_widget *w,
|
|||
case ARIZONA_OUT2R_ENA_SHIFT:
|
||||
case ARIZONA_OUT3L_ENA_SHIFT:
|
||||
case ARIZONA_OUT3R_ENA_SHIFT:
|
||||
msleep(17);
|
||||
priv->out_up_pending--;
|
||||
if (!priv->out_up_pending) {
|
||||
msleep(priv->out_up_delay);
|
||||
priv->out_up_delay = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
switch (w->shift) {
|
||||
case ARIZONA_OUT1L_ENA_SHIFT:
|
||||
case ARIZONA_OUT1R_ENA_SHIFT:
|
||||
case ARIZONA_OUT2L_ENA_SHIFT:
|
||||
case ARIZONA_OUT2R_ENA_SHIFT:
|
||||
case ARIZONA_OUT3L_ENA_SHIFT:
|
||||
case ARIZONA_OUT3R_ENA_SHIFT:
|
||||
priv->out_down_pending++;
|
||||
priv->out_down_delay++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
switch (w->shift) {
|
||||
case ARIZONA_OUT1L_ENA_SHIFT:
|
||||
case ARIZONA_OUT1R_ENA_SHIFT:
|
||||
case ARIZONA_OUT2L_ENA_SHIFT:
|
||||
case ARIZONA_OUT2R_ENA_SHIFT:
|
||||
case ARIZONA_OUT3L_ENA_SHIFT:
|
||||
case ARIZONA_OUT3R_ENA_SHIFT:
|
||||
priv->out_down_pending--;
|
||||
if (!priv->out_down_pending) {
|
||||
msleep(priv->out_down_delay);
|
||||
priv->out_down_delay = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -760,7 +816,8 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
struct arizona *arizona = priv->arizona;
|
||||
unsigned int mask = 1 << w->shift;
|
||||
unsigned int val;
|
||||
|
@ -772,6 +829,9 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w,
|
|||
case SND_SOC_DAPM_PRE_PMD:
|
||||
val = 0;
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
return arizona_out_ev(w, kcontrol, event);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -77,6 +77,11 @@ struct arizona_priv {
|
|||
int num_inputs;
|
||||
unsigned int in_pending;
|
||||
|
||||
unsigned int out_up_pending;
|
||||
unsigned int out_up_delay;
|
||||
unsigned int out_down_pending;
|
||||
unsigned int out_down_delay;
|
||||
|
||||
unsigned int spk_ena:2;
|
||||
unsigned int spk_ena_pending:1;
|
||||
};
|
||||
|
|
|
@ -86,5 +86,5 @@ static struct platform_driver bt_sco_driver = {
|
|||
module_platform_driver(bt_sco_driver);
|
||||
|
||||
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
|
||||
MODULE_DESCRIPTION("ASoC generic bluethooth sco link driver");
|
||||
MODULE_DESCRIPTION("ASoC generic bluetooth sco link driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -264,7 +264,7 @@ static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec,
|
|||
CS35L32_MCLK_DIV2_MASK | CS35L32_MCLK_RATIO_MASK, val);
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_cs35l32 = {
|
||||
static const struct snd_soc_codec_driver soc_codec_dev_cs35l32 = {
|
||||
.set_sysclk = cs35l32_codec_set_sysclk,
|
||||
|
||||
.dapm_widgets = cs35l32_dapm_widgets,
|
||||
|
@ -288,7 +288,7 @@ static const struct reg_default cs35l32_monitor_patch[] = {
|
|||
{ 0x00, 0x00 },
|
||||
};
|
||||
|
||||
static struct regmap_config cs35l32_regmap = {
|
||||
static const struct regmap_config cs35l32_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
|
|
|
@ -1103,7 +1103,7 @@ static int cs42l52_remove(struct snd_soc_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_cs42l52 = {
|
||||
static const struct snd_soc_codec_driver soc_codec_dev_cs42l52 = {
|
||||
.probe = cs42l52_probe,
|
||||
.remove = cs42l52_remove,
|
||||
.set_bias_level = cs42l52_set_bias_level,
|
||||
|
@ -1130,7 +1130,7 @@ static const struct reg_default cs42l52_threshold_patch[] = {
|
|||
|
||||
};
|
||||
|
||||
static struct regmap_config cs42l52_regmap = {
|
||||
static const struct regmap_config cs42l52_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
|
|
|
@ -1164,7 +1164,7 @@ static int cs42l56_remove(struct snd_soc_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_cs42l56 = {
|
||||
static const struct snd_soc_codec_driver soc_codec_dev_cs42l56 = {
|
||||
.probe = cs42l56_probe,
|
||||
.remove = cs42l56_remove,
|
||||
.set_bias_level = cs42l56_set_bias_level,
|
||||
|
@ -1179,7 +1179,7 @@ static struct snd_soc_codec_driver soc_codec_dev_cs42l56 = {
|
|||
.num_controls = ARRAY_SIZE(cs42l56_snd_controls),
|
||||
};
|
||||
|
||||
static struct regmap_config cs42l56_regmap = {
|
||||
static const struct regmap_config cs42l56_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
|
|
|
@ -1347,7 +1347,7 @@ static int cs42l73_probe(struct snd_soc_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
|
||||
static const struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
|
||||
.probe = cs42l73_probe,
|
||||
.set_bias_level = cs42l73_set_bias_level,
|
||||
.suspend_bias_off = true,
|
||||
|
@ -1361,7 +1361,7 @@ static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = {
|
|||
.num_controls = ARRAY_SIZE(cs42l73_snd_controls),
|
||||
};
|
||||
|
||||
static struct regmap_config cs42l73_regmap = {
|
||||
static const struct regmap_config cs42l73_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
|
|
|
@ -609,7 +609,7 @@ static const struct snd_kcontrol_new da732x_snd_controls[] = {
|
|||
static int da732x_adc_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -663,7 +663,7 @@ static int da732x_adc_event(struct snd_soc_dapm_widget *w,
|
|||
static int da732x_out_pga_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
|
|
@ -328,16 +328,16 @@ static int mc13783_set_tdm_slot_dac(struct snd_soc_dai *dai,
|
|||
}
|
||||
|
||||
switch (rx_mask) {
|
||||
case 0xfffffffc:
|
||||
case 0x03:
|
||||
val |= SSI_NETWORK_DAC_RXSLOT_0_1;
|
||||
break;
|
||||
case 0xfffffff3:
|
||||
case 0x0c:
|
||||
val |= SSI_NETWORK_DAC_RXSLOT_2_3;
|
||||
break;
|
||||
case 0xffffffcf:
|
||||
case 0x30:
|
||||
val |= SSI_NETWORK_DAC_RXSLOT_4_5;
|
||||
break;
|
||||
case 0xffffff3f:
|
||||
case 0xc0:
|
||||
val |= SSI_NETWORK_DAC_RXSLOT_6_7;
|
||||
break;
|
||||
default:
|
||||
|
@ -360,7 +360,7 @@ static int mc13783_set_tdm_slot_codec(struct snd_soc_dai *dai,
|
|||
if (slots != 4)
|
||||
return -EINVAL;
|
||||
|
||||
if (tx_mask != 0xfffffffc)
|
||||
if (tx_mask != 0x3)
|
||||
return -EINVAL;
|
||||
|
||||
val |= (0x00 << 2); /* primary timeslot RX/TX(?) is 0 */
|
||||
|
|
|
@ -32,7 +32,7 @@ static int pcm3008_dac_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct pcm3008_setup_data *setup = codec->dev->platform_data;
|
||||
|
||||
gpio_set_value_cansleep(setup->pdda_pin,
|
||||
|
@ -45,7 +45,7 @@ static int pcm3008_adc_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct pcm3008_setup_data *setup = codec->dev->platform_data;
|
||||
|
||||
gpio_set_value_cansleep(setup->pdad_pin,
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -37,6 +37,10 @@
|
|||
#define PCM512x_DSP_GPIO_INPUT (PCM512x_PAGE_BASE(0) + 10)
|
||||
#define PCM512x_MASTER_MODE (PCM512x_PAGE_BASE(0) + 12)
|
||||
#define PCM512x_PLL_REF (PCM512x_PAGE_BASE(0) + 13)
|
||||
#define PCM512x_DAC_REF (PCM512x_PAGE_BASE(0) + 14)
|
||||
#define PCM512x_GPIO_DACIN (PCM512x_PAGE_BASE(0) + 16)
|
||||
#define PCM512x_GPIO_PLLIN (PCM512x_PAGE_BASE(0) + 18)
|
||||
#define PCM512x_SYNCHRONIZE (PCM512x_PAGE_BASE(0) + 19)
|
||||
#define PCM512x_PLL_COEFF_0 (PCM512x_PAGE_BASE(0) + 20)
|
||||
#define PCM512x_PLL_COEFF_1 (PCM512x_PAGE_BASE(0) + 21)
|
||||
#define PCM512x_PLL_COEFF_2 (PCM512x_PAGE_BASE(0) + 22)
|
||||
|
@ -77,6 +81,7 @@
|
|||
#define PCM512x_RATE_DET_2 (PCM512x_PAGE_BASE(0) + 92)
|
||||
#define PCM512x_RATE_DET_3 (PCM512x_PAGE_BASE(0) + 93)
|
||||
#define PCM512x_RATE_DET_4 (PCM512x_PAGE_BASE(0) + 94)
|
||||
#define PCM512x_CLOCK_STATUS (PCM512x_PAGE_BASE(0) + 95)
|
||||
#define PCM512x_ANALOG_MUTE_DET (PCM512x_PAGE_BASE(0) + 108)
|
||||
#define PCM512x_GPIN (PCM512x_PAGE_BASE(0) + 119)
|
||||
#define PCM512x_DIGITAL_MUTE_DET (PCM512x_PAGE_BASE(0) + 120)
|
||||
|
@ -91,7 +96,10 @@
|
|||
|
||||
#define PCM512x_CRAM_CTRL (PCM512x_PAGE_BASE(44) + 1)
|
||||
|
||||
#define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(44) + 1)
|
||||
#define PCM512x_FLEX_A (PCM512x_PAGE_BASE(253) + 63)
|
||||
#define PCM512x_FLEX_B (PCM512x_PAGE_BASE(253) + 64)
|
||||
|
||||
#define PCM512x_MAX_REGISTER (PCM512x_PAGE_BASE(253) + 64)
|
||||
|
||||
/* Page 0, Register 1 - reset */
|
||||
#define PCM512x_RSTR (1 << 0)
|
||||
|
@ -108,8 +116,8 @@
|
|||
#define PCM512x_RQML_SHIFT 4
|
||||
|
||||
/* Page 0, Register 4 - PLL */
|
||||
#define PCM512x_PLCE (1 << 0)
|
||||
#define PCM512x_RLCE_SHIFT 0
|
||||
#define PCM512x_PLLE (1 << 0)
|
||||
#define PCM512x_PLLE_SHIFT 0
|
||||
#define PCM512x_PLCK (1 << 4)
|
||||
#define PCM512x_PLCK_SHIFT 4
|
||||
|
||||
|
@ -119,8 +127,66 @@
|
|||
#define PCM512x_DEMP (1 << 4)
|
||||
#define PCM512x_DEMP_SHIFT 4
|
||||
|
||||
/* Page 0, Register 8 - GPIO output enable */
|
||||
#define PCM512x_G1OE (1 << 0)
|
||||
#define PCM512x_G2OE (1 << 1)
|
||||
#define PCM512x_G3OE (1 << 2)
|
||||
#define PCM512x_G4OE (1 << 3)
|
||||
#define PCM512x_G5OE (1 << 4)
|
||||
#define PCM512x_G6OE (1 << 5)
|
||||
|
||||
/* Page 0, Register 9 - BCK, LRCLK configuration */
|
||||
#define PCM512x_LRKO (1 << 0)
|
||||
#define PCM512x_LRKO_SHIFT 0
|
||||
#define PCM512x_BCKO (1 << 4)
|
||||
#define PCM512x_BCKO_SHIFT 4
|
||||
#define PCM512x_BCKP (1 << 5)
|
||||
#define PCM512x_BCKP_SHIFT 5
|
||||
|
||||
/* Page 0, Register 12 - Master mode BCK, LRCLK reset */
|
||||
#define PCM512x_RLRK (1 << 0)
|
||||
#define PCM512x_RLRK_SHIFT 0
|
||||
#define PCM512x_RBCK (1 << 1)
|
||||
#define PCM512x_RBCK_SHIFT 1
|
||||
|
||||
/* Page 0, Register 13 - PLL reference */
|
||||
#define PCM512x_SREF (1 << 4)
|
||||
#define PCM512x_SREF (7 << 4)
|
||||
#define PCM512x_SREF_SHIFT 4
|
||||
#define PCM512x_SREF_SCK (0 << 4)
|
||||
#define PCM512x_SREF_BCK (1 << 4)
|
||||
#define PCM512x_SREF_GPIO (3 << 4)
|
||||
|
||||
/* Page 0, Register 14 - DAC reference */
|
||||
#define PCM512x_SDAC (7 << 4)
|
||||
#define PCM512x_SDAC_SHIFT 4
|
||||
#define PCM512x_SDAC_MCK (0 << 4)
|
||||
#define PCM512x_SDAC_PLL (1 << 4)
|
||||
#define PCM512x_SDAC_SCK (3 << 4)
|
||||
#define PCM512x_SDAC_BCK (4 << 4)
|
||||
#define PCM512x_SDAC_GPIO (5 << 4)
|
||||
|
||||
/* Page 0, Register 16, 18 - GPIO source for DAC, PLL */
|
||||
#define PCM512x_GREF (7 << 0)
|
||||
#define PCM512x_GREF_SHIFT 0
|
||||
#define PCM512x_GREF_GPIO1 (0 << 0)
|
||||
#define PCM512x_GREF_GPIO2 (1 << 0)
|
||||
#define PCM512x_GREF_GPIO3 (2 << 0)
|
||||
#define PCM512x_GREF_GPIO4 (3 << 0)
|
||||
#define PCM512x_GREF_GPIO5 (4 << 0)
|
||||
#define PCM512x_GREF_GPIO6 (5 << 0)
|
||||
|
||||
/* Page 0, Register 19 - synchronize */
|
||||
#define PCM512x_RQSY (1 << 0)
|
||||
#define PCM512x_RQSY_RESUME (0 << 0)
|
||||
#define PCM512x_RQSY_HALT (1 << 0)
|
||||
|
||||
/* Page 0, Register 34 - fs speed mode */
|
||||
#define PCM512x_FSSP (3 << 0)
|
||||
#define PCM512x_FSSP_SHIFT 0
|
||||
#define PCM512x_FSSP_48KHZ (0 << 0)
|
||||
#define PCM512x_FSSP_96KHZ (1 << 0)
|
||||
#define PCM512x_FSSP_192KHZ (2 << 0)
|
||||
#define PCM512x_FSSP_384KHZ (3 << 0)
|
||||
|
||||
/* Page 0, Register 37 - Error detection */
|
||||
#define PCM512x_IPLK (1 << 0)
|
||||
|
@ -131,6 +197,20 @@
|
|||
#define PCM512x_IDBK (1 << 5)
|
||||
#define PCM512x_IDFS (1 << 6)
|
||||
|
||||
/* Page 0, Register 40 - I2S configuration */
|
||||
#define PCM512x_ALEN (3 << 0)
|
||||
#define PCM512x_ALEN_SHIFT 0
|
||||
#define PCM512x_ALEN_16 (0 << 0)
|
||||
#define PCM512x_ALEN_20 (1 << 0)
|
||||
#define PCM512x_ALEN_24 (2 << 0)
|
||||
#define PCM512x_ALEN_32 (3 << 0)
|
||||
#define PCM512x_AFMT (3 << 4)
|
||||
#define PCM512x_AFMT_SHIFT 4
|
||||
#define PCM512x_AFMT_I2S (0 << 4)
|
||||
#define PCM512x_AFMT_DSP (1 << 4)
|
||||
#define PCM512x_AFMT_RTJ (2 << 4)
|
||||
#define PCM512x_AFMT_LTJ (3 << 4)
|
||||
|
||||
/* Page 0, Register 42 - DAC routing */
|
||||
#define PCM512x_AUPR_SHIFT 0
|
||||
#define PCM512x_AUPL_SHIFT 4
|
||||
|
@ -152,7 +232,26 @@
|
|||
/* Page 0, Register 65 - Digital mute enables */
|
||||
#define PCM512x_ACTL_SHIFT 2
|
||||
#define PCM512x_AMLE_SHIFT 1
|
||||
#define PCM512x_AMLR_SHIFT 0
|
||||
#define PCM512x_AMRE_SHIFT 0
|
||||
|
||||
/* Page 0, Register 80-85, GPIO output selection */
|
||||
#define PCM512x_GxSL (31 << 0)
|
||||
#define PCM512x_GxSL_SHIFT 0
|
||||
#define PCM512x_GxSL_OFF (0 << 0)
|
||||
#define PCM512x_GxSL_DSP (1 << 0)
|
||||
#define PCM512x_GxSL_REG (2 << 0)
|
||||
#define PCM512x_GxSL_AMUTB (3 << 0)
|
||||
#define PCM512x_GxSL_AMUTL (4 << 0)
|
||||
#define PCM512x_GxSL_AMUTR (5 << 0)
|
||||
#define PCM512x_GxSL_CLKI (6 << 0)
|
||||
#define PCM512x_GxSL_SDOUT (7 << 0)
|
||||
#define PCM512x_GxSL_ANMUL (8 << 0)
|
||||
#define PCM512x_GxSL_ANMUR (9 << 0)
|
||||
#define PCM512x_GxSL_PLLLK (10 << 0)
|
||||
#define PCM512x_GxSL_CPCLK (11 << 0)
|
||||
#define PCM512x_GxSL_UV0_7 (14 << 0)
|
||||
#define PCM512x_GxSL_UV0_3 (15 << 0)
|
||||
#define PCM512x_GxSL_PLLCK (16 << 0)
|
||||
|
||||
/* Page 1, Register 2 - analog volume control */
|
||||
#define PCM512x_RAGN_SHIFT 0
|
||||
|
|
|
@ -403,7 +403,8 @@ EXPORT_SYMBOL_GPL(rt286_mic_detect);
|
|||
static int is_mclk_mode(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(source->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (rt286->clk_id == RT286_SCLK_S_MCLK)
|
||||
return 1;
|
||||
|
@ -417,6 +418,8 @@ static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
|
|||
static const struct snd_kcontrol_new rt286_snd_controls[] = {
|
||||
SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT286_DACL_GAIN,
|
||||
RT286_DACR_GAIN, 0, 0x7f, 0, out_vol_tlv),
|
||||
SOC_DOUBLE_R("ADC0 Capture Switch", RT286_ADCL_GAIN,
|
||||
RT286_ADCR_GAIN, 7, 1, 1),
|
||||
SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT286_ADCL_GAIN,
|
||||
RT286_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv),
|
||||
SOC_SINGLE_TLV("AMIC Volume", RT286_MIC_GAIN,
|
||||
|
@ -500,7 +503,7 @@ SOC_DAPM_ENUM("SPO source", rt286_spo_enum);
|
|||
static int rt286_spk_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -522,7 +525,7 @@ static int rt286_spk_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -538,36 +541,10 @@ static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rt286_adc_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
unsigned int nid;
|
||||
|
||||
nid = (w->reg >> 20) & 0xff;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
snd_soc_update_bits(codec,
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
|
||||
0x7080, 0x7000);
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
snd_soc_update_bits(codec,
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
|
||||
0x7080, 0x7080);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt286_vref_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
|
@ -585,7 +562,7 @@ static int rt286_vref_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -604,7 +581,7 @@ static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt286_mic1_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
|
@ -667,12 +644,10 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM, 0, 0),
|
||||
|
||||
/* ADC Mux */
|
||||
SND_SOC_DAPM_MUX_E("ADC 0 Mux", RT286_SET_POWER(RT286_ADC_IN1), 0, 1,
|
||||
&rt286_adc0_mux, rt286_adc_event, SND_SOC_DAPM_PRE_PMD |
|
||||
SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_MUX_E("ADC 1 Mux", RT286_SET_POWER(RT286_ADC_IN2), 0, 1,
|
||||
&rt286_adc1_mux, rt286_adc_event, SND_SOC_DAPM_PRE_PMD |
|
||||
SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_MUX("ADC 0 Mux", RT286_SET_POWER(RT286_ADC_IN1), 0, 1,
|
||||
&rt286_adc0_mux),
|
||||
SND_SOC_DAPM_MUX("ADC 1 Mux", RT286_SET_POWER(RT286_ADC_IN2), 0, 1,
|
||||
&rt286_adc1_mux),
|
||||
|
||||
/* Audio Interface */
|
||||
SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
|
||||
|
|
|
@ -287,70 +287,78 @@ static const struct snd_kcontrol_new rt5631_snd_controls[] = {
|
|||
static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int reg;
|
||||
|
||||
reg = snd_soc_read(source->codec, RT5631_GLOBAL_CLK_CTRL);
|
||||
reg = snd_soc_read(codec, RT5631_GLOBAL_CLK_CTRL);
|
||||
return reg & RT5631_SYSCLK_SOUR_SEL_PLL;
|
||||
}
|
||||
|
||||
static int check_dmic_used(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(source->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
|
||||
return rt5631->dmic_used_flag;
|
||||
}
|
||||
|
||||
static int check_dacl_to_outmixl(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int reg;
|
||||
|
||||
reg = snd_soc_read(source->codec, RT5631_OUTMIXER_L_CTRL);
|
||||
reg = snd_soc_read(codec, RT5631_OUTMIXER_L_CTRL);
|
||||
return !(reg & RT5631_M_DAC_L_TO_OUTMIXER_L);
|
||||
}
|
||||
|
||||
static int check_dacr_to_outmixr(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int reg;
|
||||
|
||||
reg = snd_soc_read(source->codec, RT5631_OUTMIXER_R_CTRL);
|
||||
reg = snd_soc_read(codec, RT5631_OUTMIXER_R_CTRL);
|
||||
return !(reg & RT5631_M_DAC_R_TO_OUTMIXER_R);
|
||||
}
|
||||
|
||||
static int check_dacl_to_spkmixl(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int reg;
|
||||
|
||||
reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL);
|
||||
reg = snd_soc_read(codec, RT5631_SPK_MIXER_CTRL);
|
||||
return !(reg & RT5631_M_DAC_L_TO_SPKMIXER_L);
|
||||
}
|
||||
|
||||
static int check_dacr_to_spkmixr(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int reg;
|
||||
|
||||
reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL);
|
||||
reg = snd_soc_read(codec, RT5631_SPK_MIXER_CTRL);
|
||||
return !(reg & RT5631_M_DAC_R_TO_SPKMIXER_R);
|
||||
}
|
||||
|
||||
static int check_adcl_select(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int reg;
|
||||
|
||||
reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER);
|
||||
reg = snd_soc_read(codec, RT5631_ADC_REC_MIXER);
|
||||
return !(reg & RT5631_M_MIC1_TO_RECMIXER_L);
|
||||
}
|
||||
|
||||
static int check_adcr_select(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int reg;
|
||||
|
||||
reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER);
|
||||
reg = snd_soc_read(codec, RT5631_ADC_REC_MIXER);
|
||||
return !(reg & RT5631_M_MIC2_TO_RECMIXER_R);
|
||||
}
|
||||
|
||||
|
@ -556,7 +564,7 @@ static void depop_seq_mute_stage(struct snd_soc_codec *codec, int enable)
|
|||
static int hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -590,7 +598,7 @@ static int hp_event(struct snd_soc_dapm_widget *w,
|
|||
static int set_dmic_params(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (rt5631->rx_rate) {
|
||||
|
|
|
@ -458,7 +458,7 @@ static const struct snd_kcontrol_new rt5640_specific_snd_controls[] = {
|
|||
static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
|
||||
int idx = -EINVAL;
|
||||
|
||||
|
@ -475,9 +475,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
|||
static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int val;
|
||||
|
||||
val = snd_soc_read(source->codec, RT5640_GLB_CLK);
|
||||
val = snd_soc_read(codec, RT5640_GLB_CLK);
|
||||
val &= RT5640_SCLK_SRC_MASK;
|
||||
if (val == RT5640_SCLK_SRC_PLL1)
|
||||
return 1;
|
||||
|
@ -963,7 +964,7 @@ static void rt5640_pmu_depop(struct snd_soc_codec *codec)
|
|||
static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -987,7 +988,7 @@ static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -1003,7 +1004,7 @@ static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -2124,6 +2125,7 @@ MODULE_DEVICE_TABLE(of, rt5640_of_match);
|
|||
static struct acpi_device_id rt5640_acpi_match[] = {
|
||||
{ "INT33CA", 0 },
|
||||
{ "10EC5640", 0 },
|
||||
{ "10EC5642", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, rt5640_acpi_match);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "rt5645.h"
|
||||
|
||||
#define RT5645_DEVICE_ID 0x6308
|
||||
#define RT5650_DEVICE_ID 0x6419
|
||||
|
||||
#define RT5645_PR_RANGE_BASE (0xff + 1)
|
||||
#define RT5645_PR_SPACING 0x100
|
||||
|
@ -59,6 +60,10 @@ static const struct reg_default init_list[] = {
|
|||
};
|
||||
#define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list)
|
||||
|
||||
static const struct reg_default rt5650_init_list[] = {
|
||||
{0xf6, 0x0100},
|
||||
};
|
||||
|
||||
static const struct reg_default rt5645_reg[] = {
|
||||
{ 0x00, 0x0000 },
|
||||
{ 0x01, 0xc8c8 },
|
||||
|
@ -86,6 +91,7 @@ static const struct reg_default rt5645_reg[] = {
|
|||
{ 0x2a, 0x5656 },
|
||||
{ 0x2b, 0x5454 },
|
||||
{ 0x2c, 0xaaa0 },
|
||||
{ 0x2d, 0x0000 },
|
||||
{ 0x2f, 0x1002 },
|
||||
{ 0x31, 0x5000 },
|
||||
{ 0x32, 0x0000 },
|
||||
|
@ -193,6 +199,8 @@ static const struct reg_default rt5645_reg[] = {
|
|||
{ 0xdb, 0x0003 },
|
||||
{ 0xdc, 0x0049 },
|
||||
{ 0xdd, 0x001b },
|
||||
{ 0xdf, 0x0008 },
|
||||
{ 0xe0, 0x4000 },
|
||||
{ 0xe6, 0x8000 },
|
||||
{ 0xe7, 0x0200 },
|
||||
{ 0xec, 0xb300 },
|
||||
|
@ -242,6 +250,7 @@ static bool rt5645_volatile_register(struct device *dev, unsigned int reg)
|
|||
case RT5645_IRQ_CTRL3:
|
||||
case RT5645_INT_IRQ_ST:
|
||||
case RT5645_IL_CMD:
|
||||
case RT5650_4BTN_IL_CMD1:
|
||||
case RT5645_VENDOR_ID:
|
||||
case RT5645_VENDOR_ID1:
|
||||
case RT5645_VENDOR_ID2:
|
||||
|
@ -287,6 +296,7 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg)
|
|||
case RT5645_STO_DAC_MIXER:
|
||||
case RT5645_MONO_DAC_MIXER:
|
||||
case RT5645_DIG_MIXER:
|
||||
case RT5650_A_DAC_SOUR:
|
||||
case RT5645_DIG_INF1_DATA:
|
||||
case RT5645_PDM_OUT_CTRL:
|
||||
case RT5645_REC_L1_MIXER:
|
||||
|
@ -378,6 +388,8 @@ static bool rt5645_readable_register(struct device *dev, unsigned int reg)
|
|||
case RT5645_IL_CMD:
|
||||
case RT5645_IL_CMD2:
|
||||
case RT5645_IL_CMD3:
|
||||
case RT5650_4BTN_IL_CMD1:
|
||||
case RT5650_4BTN_IL_CMD2:
|
||||
case RT5645_DRC1_HL_CTRL1:
|
||||
case RT5645_DRC2_HL_CTRL1:
|
||||
case RT5645_ADC_MONO_HP_CTRL1:
|
||||
|
@ -527,7 +539,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
|
|||
static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
|
||||
int idx = -EINVAL;
|
||||
|
||||
|
@ -544,9 +556,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
|||
static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int val;
|
||||
|
||||
val = snd_soc_read(source->codec, RT5645_GLB_CLK);
|
||||
val = snd_soc_read(codec, RT5645_GLB_CLK);
|
||||
val &= RT5645_SCLK_SRC_MASK;
|
||||
if (val == RT5645_SCLK_SRC_PLL1)
|
||||
return 1;
|
||||
|
@ -557,6 +570,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
|
|||
static int is_using_asrc(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int reg, shift, val;
|
||||
|
||||
switch (source->shift) {
|
||||
|
@ -588,7 +602,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
|
|||
return 0;
|
||||
}
|
||||
|
||||
val = (snd_soc_read(source->codec, reg) >> shift) & 0xf;
|
||||
val = (snd_soc_read(codec, reg) >> shift) & 0xf;
|
||||
switch (val) {
|
||||
case 1:
|
||||
case 2:
|
||||
|
@ -1007,6 +1021,44 @@ static SOC_ENUM_SINGLE_DECL(
|
|||
static const struct snd_kcontrol_new rt5645_if1_adc_in_mux =
|
||||
SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum);
|
||||
|
||||
/* MX-2d [3] [2] */
|
||||
static const char * const rt5650_a_dac1_src[] = {
|
||||
"DAC1", "Stereo DAC Mixer"
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(
|
||||
rt5650_a_dac1_l_enum, RT5650_A_DAC_SOUR,
|
||||
RT5650_A_DAC1_L_IN_SFT, rt5650_a_dac1_src);
|
||||
|
||||
static const struct snd_kcontrol_new rt5650_a_dac1_l_mux =
|
||||
SOC_DAPM_ENUM("A DAC1 L source", rt5650_a_dac1_l_enum);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(
|
||||
rt5650_a_dac1_r_enum, RT5650_A_DAC_SOUR,
|
||||
RT5650_A_DAC1_R_IN_SFT, rt5650_a_dac1_src);
|
||||
|
||||
static const struct snd_kcontrol_new rt5650_a_dac1_r_mux =
|
||||
SOC_DAPM_ENUM("A DAC1 R source", rt5650_a_dac1_r_enum);
|
||||
|
||||
/* MX-2d [1] [0] */
|
||||
static const char * const rt5650_a_dac2_src[] = {
|
||||
"Stereo DAC Mixer", "Mono DAC Mixer"
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(
|
||||
rt5650_a_dac2_l_enum, RT5650_A_DAC_SOUR,
|
||||
RT5650_A_DAC2_L_IN_SFT, rt5650_a_dac2_src);
|
||||
|
||||
static const struct snd_kcontrol_new rt5650_a_dac2_l_mux =
|
||||
SOC_DAPM_ENUM("A DAC2 L source", rt5650_a_dac2_l_enum);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(
|
||||
rt5650_a_dac2_r_enum, RT5650_A_DAC_SOUR,
|
||||
RT5650_A_DAC2_R_IN_SFT, rt5650_a_dac2_src);
|
||||
|
||||
static const struct snd_kcontrol_new rt5650_a_dac2_r_mux =
|
||||
SOC_DAPM_ENUM("A DAC2 R source", rt5650_a_dac2_r_enum);
|
||||
|
||||
/* MX-2F [13:12] */
|
||||
static const char * const rt5645_if2_adc_in_src[] = {
|
||||
"IF_ADC1", "IF_ADC2", "VAD_ADC"
|
||||
|
@ -1144,18 +1196,23 @@ static void hp_amp_power(struct snd_soc_codec *codec, int on)
|
|||
static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
hp_amp_power(codec, 1);
|
||||
/* headphone unmute sequence */
|
||||
snd_soc_update_bits(codec, RT5645_DEPOP_M3, RT5645_CP_FQ1_MASK |
|
||||
RT5645_CP_FQ2_MASK | RT5645_CP_FQ3_MASK,
|
||||
(RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) |
|
||||
(RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
|
||||
(RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT));
|
||||
if (rt5645->codec_type == CODEC_TYPE_RT5650) {
|
||||
snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);
|
||||
} else {
|
||||
snd_soc_update_bits(codec, RT5645_DEPOP_M3,
|
||||
RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
|
||||
RT5645_CP_FQ3_MASK,
|
||||
(RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) |
|
||||
(RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
|
||||
(RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT));
|
||||
}
|
||||
regmap_write(rt5645->regmap,
|
||||
RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00);
|
||||
snd_soc_update_bits(codec, RT5645_DEPOP_M1,
|
||||
|
@ -1175,12 +1232,16 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
|
|||
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
/* headphone mute sequence */
|
||||
snd_soc_update_bits(codec, RT5645_DEPOP_M3,
|
||||
RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
|
||||
RT5645_CP_FQ3_MASK,
|
||||
(RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) |
|
||||
(RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
|
||||
(RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT));
|
||||
if (rt5645->codec_type == CODEC_TYPE_RT5650) {
|
||||
snd_soc_write(codec, RT5645_DEPOP_M3, 0x0737);
|
||||
} else {
|
||||
snd_soc_update_bits(codec, RT5645_DEPOP_M3,
|
||||
RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
|
||||
RT5645_CP_FQ3_MASK,
|
||||
(RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) |
|
||||
(RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
|
||||
(RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT));
|
||||
}
|
||||
regmap_write(rt5645->regmap,
|
||||
RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00);
|
||||
snd_soc_update_bits(codec, RT5645_DEPOP_M1,
|
||||
|
@ -1205,7 +1266,7 @@ static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -1232,7 +1293,7 @@ static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5645_lout_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -1262,7 +1323,7 @@ static int rt5645_lout_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5645_bst2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -1574,6 +1635,17 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_OUTPUT("SPOR"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget rt5650_specific_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_MUX("A DAC1 L Mux", SND_SOC_NOPM,
|
||||
0, 0, &rt5650_a_dac1_l_mux),
|
||||
SND_SOC_DAPM_MUX("A DAC1 R Mux", SND_SOC_NOPM,
|
||||
0, 0, &rt5650_a_dac1_r_mux),
|
||||
SND_SOC_DAPM_MUX("A DAC2 L Mux", SND_SOC_NOPM,
|
||||
0, 0, &rt5650_a_dac2_l_mux),
|
||||
SND_SOC_DAPM_MUX("A DAC2 R Mux", SND_SOC_NOPM,
|
||||
0, 0, &rt5650_a_dac2_r_mux),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
|
||||
{ "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc },
|
||||
{ "adc stereo2 filter", NULL, "ADC STO2 ASRC", is_using_asrc },
|
||||
|
@ -1779,13 +1851,9 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
|
|||
{ "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
|
||||
{ "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
|
||||
|
||||
{ "DAC L1", NULL, "Stereo DAC MIXL" },
|
||||
{ "DAC L1", NULL, "PLL1", is_sys_clk_from_pll },
|
||||
{ "DAC R1", NULL, "Stereo DAC MIXR" },
|
||||
{ "DAC R1", NULL, "PLL1", is_sys_clk_from_pll },
|
||||
{ "DAC L2", NULL, "Mono DAC MIXL" },
|
||||
{ "DAC L2", NULL, "PLL1", is_sys_clk_from_pll },
|
||||
{ "DAC R2", NULL, "Mono DAC MIXR" },
|
||||
{ "DAC R2", NULL, "PLL1", is_sys_clk_from_pll },
|
||||
|
||||
{ "SPK MIXL", "BST1 Switch", "BST1" },
|
||||
|
@ -1874,6 +1942,30 @@ static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
|
|||
{ "SPOR", NULL, "SPK amp" },
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rt5650_specific_dapm_routes[] = {
|
||||
{ "A DAC1 L Mux", "DAC1", "DAC1 MIXL"},
|
||||
{ "A DAC1 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"},
|
||||
{ "A DAC1 R Mux", "DAC1", "DAC1 MIXR"},
|
||||
{ "A DAC1 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"},
|
||||
|
||||
{ "A DAC2 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"},
|
||||
{ "A DAC2 L Mux", "Mono DAC Mixer", "Mono DAC MIXL"},
|
||||
{ "A DAC2 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"},
|
||||
{ "A DAC2 R Mux", "Mono DAC Mixer", "Mono DAC MIXR"},
|
||||
|
||||
{ "DAC L1", NULL, "A DAC1 L Mux" },
|
||||
{ "DAC R1", NULL, "A DAC1 R Mux" },
|
||||
{ "DAC L2", NULL, "A DAC2 L Mux" },
|
||||
{ "DAC R2", NULL, "A DAC2 R Mux" },
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rt5645_specific_dapm_routes[] = {
|
||||
{ "DAC L1", NULL, "Stereo DAC MIXL" },
|
||||
{ "DAC R1", NULL, "Stereo DAC MIXR" },
|
||||
{ "DAC L2", NULL, "Mono DAC MIXL" },
|
||||
{ "DAC R2", NULL, "Mono DAC MIXR" },
|
||||
};
|
||||
|
||||
static int rt5645_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
|
||||
{
|
||||
|
@ -2293,6 +2385,22 @@ static int rt5645_probe(struct snd_soc_codec *codec)
|
|||
|
||||
rt5645->codec = codec;
|
||||
|
||||
switch (rt5645->codec_type) {
|
||||
case CODEC_TYPE_RT5645:
|
||||
snd_soc_dapm_add_routes(&codec->dapm,
|
||||
rt5645_specific_dapm_routes,
|
||||
ARRAY_SIZE(rt5645_specific_dapm_routes));
|
||||
break;
|
||||
case CODEC_TYPE_RT5650:
|
||||
snd_soc_dapm_new_controls(&codec->dapm,
|
||||
rt5650_specific_dapm_widgets,
|
||||
ARRAY_SIZE(rt5650_specific_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(&codec->dapm,
|
||||
rt5650_specific_dapm_routes,
|
||||
ARRAY_SIZE(rt5650_specific_dapm_routes));
|
||||
break;
|
||||
}
|
||||
|
||||
rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||
|
||||
snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200);
|
||||
|
@ -2424,6 +2532,7 @@ static const struct regmap_config rt5645_regmap = {
|
|||
|
||||
static const struct i2c_device_id rt5645_i2c_id[] = {
|
||||
{ "rt5645", 0 },
|
||||
{ "rt5650", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
|
||||
|
@ -2456,9 +2565,18 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
|
|||
}
|
||||
|
||||
regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val);
|
||||
if (val != RT5645_DEVICE_ID) {
|
||||
|
||||
switch (val) {
|
||||
case RT5645_DEVICE_ID:
|
||||
rt5645->codec_type = CODEC_TYPE_RT5645;
|
||||
break;
|
||||
case RT5650_DEVICE_ID:
|
||||
rt5645->codec_type = CODEC_TYPE_RT5650;
|
||||
break;
|
||||
default:
|
||||
dev_err(&i2c->dev,
|
||||
"Device with ID register %x is not rt5645\n", val);
|
||||
"Device with ID register %x is not rt5645 or rt5650\n",
|
||||
val);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -2469,6 +2587,14 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
|
|||
if (ret != 0)
|
||||
dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
|
||||
|
||||
if (rt5645->codec_type == CODEC_TYPE_RT5650) {
|
||||
ret = regmap_register_patch(rt5645->regmap, rt5650_init_list,
|
||||
ARRAY_SIZE(rt5650_init_list));
|
||||
if (ret != 0)
|
||||
dev_warn(&i2c->dev, "Apply rt5650 patch failed: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
if (rt5645->pdata.in2_diff)
|
||||
regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL,
|
||||
RT5645_IN_DF2, RT5645_IN_DF2);
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#define RT5645_STO_DAC_MIXER 0x2a
|
||||
#define RT5645_MONO_DAC_MIXER 0x2b
|
||||
#define RT5645_DIG_MIXER 0x2c
|
||||
#define RT5650_A_DAC_SOUR 0x2d
|
||||
#define RT5645_DIG_INF1_DATA 0x2f
|
||||
/* Mixer - PDM */
|
||||
#define RT5645_PDM_OUT_CTRL 0x31
|
||||
|
@ -150,6 +151,8 @@
|
|||
#define RT5645_IL_CMD 0xdb
|
||||
#define RT5645_IL_CMD2 0xdc
|
||||
#define RT5645_IL_CMD3 0xdd
|
||||
#define RT5650_4BTN_IL_CMD1 0xdf
|
||||
#define RT5650_4BTN_IL_CMD2 0xe0
|
||||
#define RT5645_DRC1_HL_CTRL1 0xe7
|
||||
#define RT5645_DRC2_HL_CTRL1 0xe9
|
||||
#define RT5645_MUTI_DRC_CTRL1 0xea
|
||||
|
@ -472,6 +475,12 @@
|
|||
#define RT5645_DAC_L2_DAC_R_VOL_MASK (0x1 << 4)
|
||||
#define RT5645_DAC_L2_DAC_R_VOL_SFT 4
|
||||
|
||||
/* Analog DAC1/2 Input Source Control (0x2d) */
|
||||
#define RT5650_A_DAC1_L_IN_SFT 3
|
||||
#define RT5650_A_DAC1_R_IN_SFT 2
|
||||
#define RT5650_A_DAC2_L_IN_SFT 1
|
||||
#define RT5650_A_DAC2_R_IN_SFT 0
|
||||
|
||||
/* Digital Interface Data Control (0x2f) */
|
||||
#define RT5645_IF1_ADC2_IN_SEL (0x1 << 15)
|
||||
#define RT5645_IF1_ADC2_IN_SFT 15
|
||||
|
@ -2175,6 +2184,11 @@ enum {
|
|||
RT5645_DMIC_DATA_GPIO11,
|
||||
};
|
||||
|
||||
enum {
|
||||
CODEC_TYPE_RT5645,
|
||||
CODEC_TYPE_RT5650,
|
||||
};
|
||||
|
||||
struct rt5645_priv {
|
||||
struct snd_soc_codec *codec;
|
||||
struct rt5645_platform_data pdata;
|
||||
|
@ -2184,6 +2198,7 @@ struct rt5645_priv {
|
|||
struct snd_soc_jack *mic_jack;
|
||||
struct delayed_work jack_detect_work;
|
||||
|
||||
int codec_type;
|
||||
int sysclk;
|
||||
int sysclk_src;
|
||||
int lrck[RT5645_AIFS];
|
||||
|
|
|
@ -376,7 +376,7 @@ static const struct snd_kcontrol_new rt5651_snd_controls[] = {
|
|||
static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
|
||||
int idx = -EINVAL;
|
||||
|
||||
|
@ -394,9 +394,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
|||
static int is_sysclk_from_pll(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int val;
|
||||
|
||||
val = snd_soc_read(source->codec, RT5651_GLB_CLK);
|
||||
val = snd_soc_read(codec, RT5651_GLB_CLK);
|
||||
val &= RT5651_SCLK_SRC_MASK;
|
||||
if (val == RT5651_SCLK_SRC_PLL1)
|
||||
return 1;
|
||||
|
@ -731,7 +732,7 @@ static const struct snd_kcontrol_new rt5651_pdm_r_mux =
|
|||
static int rt5651_amp_power_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -769,7 +770,7 @@ static int rt5651_amp_power_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5651_hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -813,7 +814,8 @@ static int rt5651_hp_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5651_hp_post_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -833,7 +835,7 @@ static int rt5651_hp_post_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5651_bst1_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -856,7 +858,7 @@ static int rt5651_bst1_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5651_bst2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -879,7 +881,7 @@ static int rt5651_bst2_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5651_bst3_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
|
|
@ -500,7 +500,7 @@ static const struct snd_kcontrol_new rt5670_snd_controls[] = {
|
|||
static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
|
||||
int idx = -EINVAL;
|
||||
|
||||
|
@ -517,9 +517,10 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
|||
static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int val;
|
||||
|
||||
val = snd_soc_read(source->codec, RT5670_GLB_CLK);
|
||||
val = snd_soc_read(codec, RT5670_GLB_CLK);
|
||||
val &= RT5670_SCLK_SRC_MASK;
|
||||
if (val == RT5670_SCLK_SRC_PLL1)
|
||||
return 1;
|
||||
|
@ -530,6 +531,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
|
|||
static int is_using_asrc(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int reg, shift, val;
|
||||
|
||||
switch (source->shift) {
|
||||
|
@ -565,7 +567,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
|
|||
return 0;
|
||||
}
|
||||
|
||||
val = (snd_soc_read(source->codec, reg) >> shift) & 0xf;
|
||||
val = (snd_soc_read(codec, reg) >> shift) & 0xf;
|
||||
switch (val) {
|
||||
case 1:
|
||||
case 2:
|
||||
|
@ -590,6 +592,89 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* rt5670_sel_asrc_clk_src - select ASRC clock source for a set of filters
|
||||
* @codec: SoC audio codec device.
|
||||
* @filter_mask: mask of filters.
|
||||
* @clk_src: clock source
|
||||
*
|
||||
* The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5670 can
|
||||
* only support standard 32fs or 64fs i2s format, ASRC should be enabled to
|
||||
* support special i2s clock format such as Intel's 100fs(100 * sampling rate).
|
||||
* ASRC function will track i2s clock and generate a corresponding system clock
|
||||
* for codec. This function provides an API to select the clock source for a
|
||||
* set of filters specified by the mask. And the codec driver will turn on ASRC
|
||||
* for these filters if ASRC is selected as their clock source.
|
||||
*/
|
||||
int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
|
||||
unsigned int filter_mask, unsigned int clk_src)
|
||||
{
|
||||
unsigned int asrc2_mask = 0, asrc2_value = 0;
|
||||
unsigned int asrc3_mask = 0, asrc3_value = 0;
|
||||
|
||||
if (clk_src > RT5670_CLK_SEL_SYS3)
|
||||
return -EINVAL;
|
||||
|
||||
if (filter_mask & RT5670_DA_STEREO_FILTER) {
|
||||
asrc2_mask |= RT5670_DA_STO_CLK_SEL_MASK;
|
||||
asrc2_value = (asrc2_value & ~RT5670_DA_STO_CLK_SEL_MASK)
|
||||
| (clk_src << RT5670_DA_STO_CLK_SEL_SFT);
|
||||
}
|
||||
|
||||
if (filter_mask & RT5670_DA_MONO_L_FILTER) {
|
||||
asrc2_mask |= RT5670_DA_MONOL_CLK_SEL_MASK;
|
||||
asrc2_value = (asrc2_value & ~RT5670_DA_MONOL_CLK_SEL_MASK)
|
||||
| (clk_src << RT5670_DA_MONOL_CLK_SEL_SFT);
|
||||
}
|
||||
|
||||
if (filter_mask & RT5670_DA_MONO_R_FILTER) {
|
||||
asrc2_mask |= RT5670_DA_MONOR_CLK_SEL_MASK;
|
||||
asrc2_value = (asrc2_value & ~RT5670_DA_MONOR_CLK_SEL_MASK)
|
||||
| (clk_src << RT5670_DA_MONOR_CLK_SEL_SFT);
|
||||
}
|
||||
|
||||
if (filter_mask & RT5670_AD_STEREO_FILTER) {
|
||||
asrc2_mask |= RT5670_AD_STO1_CLK_SEL_MASK;
|
||||
asrc2_value = (asrc2_value & ~RT5670_AD_STO1_CLK_SEL_MASK)
|
||||
| (clk_src << RT5670_AD_STO1_CLK_SEL_SFT);
|
||||
}
|
||||
|
||||
if (filter_mask & RT5670_AD_MONO_L_FILTER) {
|
||||
asrc3_mask |= RT5670_AD_MONOL_CLK_SEL_MASK;
|
||||
asrc3_value = (asrc3_value & ~RT5670_AD_MONOL_CLK_SEL_MASK)
|
||||
| (clk_src << RT5670_AD_MONOL_CLK_SEL_SFT);
|
||||
}
|
||||
|
||||
if (filter_mask & RT5670_AD_MONO_R_FILTER) {
|
||||
asrc3_mask |= RT5670_AD_MONOR_CLK_SEL_MASK;
|
||||
asrc3_value = (asrc3_value & ~RT5670_AD_MONOR_CLK_SEL_MASK)
|
||||
| (clk_src << RT5670_AD_MONOR_CLK_SEL_SFT);
|
||||
}
|
||||
|
||||
if (filter_mask & RT5670_UP_RATE_FILTER) {
|
||||
asrc3_mask |= RT5670_UP_CLK_SEL_MASK;
|
||||
asrc3_value = (asrc3_value & ~RT5670_UP_CLK_SEL_MASK)
|
||||
| (clk_src << RT5670_UP_CLK_SEL_SFT);
|
||||
}
|
||||
|
||||
if (filter_mask & RT5670_DOWN_RATE_FILTER) {
|
||||
asrc3_mask |= RT5670_DOWN_CLK_SEL_MASK;
|
||||
asrc3_value = (asrc3_value & ~RT5670_DOWN_CLK_SEL_MASK)
|
||||
| (clk_src << RT5670_DOWN_CLK_SEL_SFT);
|
||||
}
|
||||
|
||||
if (asrc2_mask)
|
||||
snd_soc_update_bits(codec, RT5670_ASRC_2,
|
||||
asrc2_mask, asrc2_value);
|
||||
|
||||
if (asrc3_mask)
|
||||
snd_soc_update_bits(codec, RT5670_ASRC_3,
|
||||
asrc3_mask, asrc3_value);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt5670_sel_asrc_clk_src);
|
||||
|
||||
/* Digital Mixer */
|
||||
static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = {
|
||||
SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
|
||||
|
@ -1148,7 +1233,7 @@ static const struct snd_kcontrol_new rt5670_vad_adc_mux =
|
|||
static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -1184,7 +1269,7 @@ static int rt5670_hp_power_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -1234,7 +1319,7 @@ static int rt5670_hp_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
@ -1257,7 +1342,7 @@ static int rt5670_bst1_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5670_bst2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
|
|
@ -1023,50 +1023,33 @@
|
|||
#define RT5670_DMIC_2_M_NOR (0x0 << 8)
|
||||
#define RT5670_DMIC_2_M_ASYN (0x1 << 8)
|
||||
|
||||
/* ASRC clock source selection (0x84, 0x85) */
|
||||
#define RT5670_CLK_SEL_SYS (0x0)
|
||||
#define RT5670_CLK_SEL_I2S1_ASRC (0x1)
|
||||
#define RT5670_CLK_SEL_I2S2_ASRC (0x2)
|
||||
#define RT5670_CLK_SEL_I2S3_ASRC (0x3)
|
||||
#define RT5670_CLK_SEL_SYS2 (0x5)
|
||||
#define RT5670_CLK_SEL_SYS3 (0x6)
|
||||
|
||||
/* ASRC Control 2 (0x84) */
|
||||
#define RT5670_MDA_L_M_MASK (0x1 << 15)
|
||||
#define RT5670_MDA_L_M_SFT 15
|
||||
#define RT5670_MDA_L_M_NOR (0x0 << 15)
|
||||
#define RT5670_MDA_L_M_ASYN (0x1 << 15)
|
||||
#define RT5670_MDA_R_M_MASK (0x1 << 14)
|
||||
#define RT5670_MDA_R_M_SFT 14
|
||||
#define RT5670_MDA_R_M_NOR (0x0 << 14)
|
||||
#define RT5670_MDA_R_M_ASYN (0x1 << 14)
|
||||
#define RT5670_MAD_L_M_MASK (0x1 << 13)
|
||||
#define RT5670_MAD_L_M_SFT 13
|
||||
#define RT5670_MAD_L_M_NOR (0x0 << 13)
|
||||
#define RT5670_MAD_L_M_ASYN (0x1 << 13)
|
||||
#define RT5670_MAD_R_M_MASK (0x1 << 12)
|
||||
#define RT5670_MAD_R_M_SFT 12
|
||||
#define RT5670_MAD_R_M_NOR (0x0 << 12)
|
||||
#define RT5670_MAD_R_M_ASYN (0x1 << 12)
|
||||
#define RT5670_ADC_M_MASK (0x1 << 11)
|
||||
#define RT5670_ADC_M_SFT 11
|
||||
#define RT5670_ADC_M_NOR (0x0 << 11)
|
||||
#define RT5670_ADC_M_ASYN (0x1 << 11)
|
||||
#define RT5670_STO_DAC_M_MASK (0x1 << 5)
|
||||
#define RT5670_STO_DAC_M_SFT 5
|
||||
#define RT5670_STO_DAC_M_NOR (0x0 << 5)
|
||||
#define RT5670_STO_DAC_M_ASYN (0x1 << 5)
|
||||
#define RT5670_I2S1_R_D_MASK (0x1 << 4)
|
||||
#define RT5670_I2S1_R_D_SFT 4
|
||||
#define RT5670_I2S1_R_D_DIS (0x0 << 4)
|
||||
#define RT5670_I2S1_R_D_EN (0x1 << 4)
|
||||
#define RT5670_I2S2_R_D_MASK (0x1 << 3)
|
||||
#define RT5670_I2S2_R_D_SFT 3
|
||||
#define RT5670_I2S2_R_D_DIS (0x0 << 3)
|
||||
#define RT5670_I2S2_R_D_EN (0x1 << 3)
|
||||
#define RT5670_PRE_SCLK_MASK (0x3)
|
||||
#define RT5670_PRE_SCLK_SFT 0
|
||||
#define RT5670_PRE_SCLK_512 (0x0)
|
||||
#define RT5670_PRE_SCLK_1024 (0x1)
|
||||
#define RT5670_PRE_SCLK_2048 (0x2)
|
||||
#define RT5670_DA_STO_CLK_SEL_MASK (0xf << 12)
|
||||
#define RT5670_DA_STO_CLK_SEL_SFT 12
|
||||
#define RT5670_DA_MONOL_CLK_SEL_MASK (0xf << 8)
|
||||
#define RT5670_DA_MONOL_CLK_SEL_SFT 8
|
||||
#define RT5670_DA_MONOR_CLK_SEL_MASK (0xf << 4)
|
||||
#define RT5670_DA_MONOR_CLK_SEL_SFT 4
|
||||
#define RT5670_AD_STO1_CLK_SEL_MASK (0xf << 0)
|
||||
#define RT5670_AD_STO1_CLK_SEL_SFT 0
|
||||
|
||||
/* ASRC Control 3 (0x85) */
|
||||
#define RT5670_I2S1_RATE_MASK (0xf << 12)
|
||||
#define RT5670_I2S1_RATE_SFT 12
|
||||
#define RT5670_I2S2_RATE_MASK (0xf << 8)
|
||||
#define RT5670_I2S2_RATE_SFT 8
|
||||
#define RT5670_UP_CLK_SEL_MASK (0xf << 12)
|
||||
#define RT5670_UP_CLK_SEL_SFT 12
|
||||
#define RT5670_DOWN_CLK_SEL_MASK (0xf << 8)
|
||||
#define RT5670_DOWN_CLK_SEL_SFT 8
|
||||
#define RT5670_AD_MONOL_CLK_SEL_MASK (0xf << 4)
|
||||
#define RT5670_AD_MONOL_CLK_SEL_SFT 4
|
||||
#define RT5670_AD_MONOR_CLK_SEL_MASK (0xf << 0)
|
||||
#define RT5670_AD_MONOR_CLK_SEL_SFT 0
|
||||
|
||||
/* ASRC Control 4 (0x89) */
|
||||
#define RT5670_I2S1_PD_MASK (0x7 << 12)
|
||||
|
@ -1983,6 +1966,21 @@ enum {
|
|||
RT5670_DMIC_DATA_GPIO5,
|
||||
};
|
||||
|
||||
/* filter mask */
|
||||
enum {
|
||||
RT5670_DA_STEREO_FILTER = 0x1,
|
||||
RT5670_DA_MONO_L_FILTER = (0x1 << 1),
|
||||
RT5670_DA_MONO_R_FILTER = (0x1 << 2),
|
||||
RT5670_AD_STEREO_FILTER = (0x1 << 3),
|
||||
RT5670_AD_MONO_L_FILTER = (0x1 << 4),
|
||||
RT5670_AD_MONO_R_FILTER = (0x1 << 5),
|
||||
RT5670_UP_RATE_FILTER = (0x1 << 6),
|
||||
RT5670_DOWN_RATE_FILTER = (0x1 << 7),
|
||||
};
|
||||
|
||||
int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
|
||||
unsigned int filter_mask, unsigned int clk_src);
|
||||
|
||||
struct rt5670_priv {
|
||||
struct snd_soc_codec *codec;
|
||||
struct rt5670_platform_data pdata;
|
||||
|
|
|
@ -702,6 +702,9 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on)
|
|||
static bool activity;
|
||||
int ret;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_SND_SOC_RT5677_SPI))
|
||||
return -ENXIO;
|
||||
|
||||
if (on && !activity) {
|
||||
activity = true;
|
||||
|
||||
|
@ -896,7 +899,7 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
|
|||
static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
int idx = rl6231_calc_dmic_clk(rt5677->sysclk);
|
||||
|
||||
|
@ -911,7 +914,8 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
|
|||
static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(source->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int val;
|
||||
|
||||
regmap_read(rt5677->regmap, RT5677_GLB_CLK1, &val);
|
||||
|
@ -925,6 +929,8 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
|
|||
static int is_using_asrc(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int reg, shift, val;
|
||||
|
||||
if (source->reg == RT5677_ASRC_1) {
|
||||
|
@ -991,7 +997,9 @@ static int is_using_asrc(struct snd_soc_dapm_widget *source,
|
|||
}
|
||||
}
|
||||
|
||||
val = (snd_soc_read(source->codec, reg) >> shift) & 0xf;
|
||||
regmap_read(rt5677->regmap, reg, &val);
|
||||
val = (val >> shift) & 0xf;
|
||||
|
||||
switch (val) {
|
||||
case 1 ... 6:
|
||||
return 1;
|
||||
|
@ -2122,7 +2130,7 @@ static const struct snd_kcontrol_new rt5677_if2_dac7_tdm_sel_mux =
|
|||
static int rt5677_bst1_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -2146,7 +2154,7 @@ static int rt5677_bst1_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5677_bst2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -2170,7 +2178,7 @@ static int rt5677_bst2_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -2192,7 +2200,7 @@ static int rt5677_set_pll1_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -2214,7 +2222,7 @@ static int rt5677_set_pll2_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -2241,7 +2249,7 @@ static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int value;
|
||||
|
||||
|
@ -2264,7 +2272,7 @@ static int rt5677_if1_adc_tdm_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int value;
|
||||
|
||||
|
@ -2287,7 +2295,7 @@ static int rt5677_if2_adc_tdm_event(struct snd_soc_dapm_widget *w,
|
|||
static int rt5677_vref_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -4098,7 +4106,8 @@ static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
|
|||
unsigned int rx_mask, int slots, int slot_width)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
unsigned int val = 0;
|
||||
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int val = 0, slot_width_25 = 0;
|
||||
|
||||
if (rx_mask || tx_mask)
|
||||
val |= (1 << 12);
|
||||
|
@ -4122,6 +4131,8 @@ static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
|
|||
case 20:
|
||||
val |= (1 << 8);
|
||||
break;
|
||||
case 25:
|
||||
slot_width_25 = 0x8080;
|
||||
case 24:
|
||||
val |= (2 << 8);
|
||||
break;
|
||||
|
@ -4135,10 +4146,16 @@ static int rt5677_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
|
|||
|
||||
switch (dai->id) {
|
||||
case RT5677_AIF1:
|
||||
snd_soc_update_bits(codec, RT5677_TDM1_CTRL1, 0x1f00, val);
|
||||
regmap_update_bits(rt5677->regmap, RT5677_TDM1_CTRL1, 0x1f00,
|
||||
val);
|
||||
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x8000,
|
||||
slot_width_25);
|
||||
break;
|
||||
case RT5677_AIF2:
|
||||
snd_soc_update_bits(codec, RT5677_TDM2_CTRL1, 0x1f00, val);
|
||||
regmap_update_bits(rt5677->regmap, RT5677_TDM2_CTRL1, 0x1f00,
|
||||
val);
|
||||
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x80,
|
||||
slot_width_25);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -4923,6 +4940,11 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
|
|||
RT5677_GPIO5_DIR_OUT);
|
||||
}
|
||||
|
||||
if (rt5677->pdata.micbias1_vdd_3v3)
|
||||
regmap_update_bits(rt5677->regmap, RT5677_MICBIAS,
|
||||
RT5677_MICBIAS1_CTRL_VDD_MASK,
|
||||
RT5677_MICBIAS1_CTRL_VDD_3_3V);
|
||||
|
||||
rt5677_init_gpio(i2c);
|
||||
rt5677_init_irq(i2c);
|
||||
|
||||
|
|
|
@ -155,18 +155,19 @@ struct sgtl5000_priv {
|
|||
static int mic_bias_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/* change mic bias resistor */
|
||||
snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
|
||||
snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
|
||||
SGTL5000_BIAS_R_MASK,
|
||||
sgtl5000->micbias_resistor << SGTL5000_BIAS_R_SHIFT);
|
||||
break;
|
||||
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL,
|
||||
snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
|
||||
SGTL5000_BIAS_R_MASK, 0);
|
||||
break;
|
||||
}
|
||||
|
@ -181,11 +182,12 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
|
|||
static int power_vag_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
const u32 mask = SGTL5000_DAC_POWERUP | SGTL5000_ADC_POWERUP;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
|
||||
snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
|
||||
SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
|
||||
break;
|
||||
|
||||
|
@ -195,9 +197,9 @@ static int power_vag_event(struct snd_soc_dapm_widget *w,
|
|||
* operational to prevent inadvertently starving the
|
||||
* other one of them.
|
||||
*/
|
||||
if ((snd_soc_read(w->codec, SGTL5000_CHIP_ANA_POWER) &
|
||||
if ((snd_soc_read(codec, SGTL5000_CHIP_ANA_POWER) &
|
||||
mask) != mask) {
|
||||
snd_soc_update_bits(w->codec, SGTL5000_CHIP_ANA_POWER,
|
||||
snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER,
|
||||
SGTL5000_VAG_POWERUP, 0);
|
||||
msleep(400);
|
||||
}
|
||||
|
@ -483,21 +485,21 @@ static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
|
|||
/* setting i2s data format */
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
i2sctl |= SGTL5000_I2S_MODE_PCM;
|
||||
i2sctl |= SGTL5000_I2S_MODE_PCM << SGTL5000_I2S_MODE_SHIFT;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
i2sctl |= SGTL5000_I2S_MODE_PCM;
|
||||
i2sctl |= SGTL5000_I2S_MODE_PCM << SGTL5000_I2S_MODE_SHIFT;
|
||||
i2sctl |= SGTL5000_I2S_LRALIGN;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
|
||||
i2sctl |= SGTL5000_I2S_MODE_I2S_LJ << SGTL5000_I2S_MODE_SHIFT;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_RIGHT_J:
|
||||
i2sctl |= SGTL5000_I2S_MODE_RJ;
|
||||
i2sctl |= SGTL5000_I2S_MODE_RJ << SGTL5000_I2S_MODE_SHIFT;
|
||||
i2sctl |= SGTL5000_I2S_LRPOL;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
i2sctl |= SGTL5000_I2S_MODE_I2S_LJ;
|
||||
i2sctl |= SGTL5000_I2S_MODE_I2S_LJ << SGTL5000_I2S_MODE_SHIFT;
|
||||
i2sctl |= SGTL5000_I2S_LRALIGN;
|
||||
break;
|
||||
default:
|
||||
|
@ -1462,6 +1464,9 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Need 8 clocks before I2C accesses */
|
||||
udelay(1);
|
||||
|
||||
/* read chip information */
|
||||
ret = regmap_read(sgtl5000->regmap, SGTL5000_CHIP_ID, ®);
|
||||
if (ret)
|
||||
|
|
|
@ -233,16 +233,18 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
|
|||
static int sn95031_vhs_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
|
||||
/* power up the rail */
|
||||
snd_soc_write(w->codec, SN95031_VHSP, 0x3D);
|
||||
snd_soc_write(w->codec, SN95031_VHSN, 0x3F);
|
||||
snd_soc_write(codec, SN95031_VHSP, 0x3D);
|
||||
snd_soc_write(codec, SN95031_VHSN, 0x3F);
|
||||
msleep(1);
|
||||
} else if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||
pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
|
||||
snd_soc_write(w->codec, SN95031_VHSP, 0xC4);
|
||||
snd_soc_write(w->codec, SN95031_VHSN, 0x04);
|
||||
snd_soc_write(codec, SN95031_VHSP, 0xC4);
|
||||
snd_soc_write(codec, SN95031_VHSN, 0x04);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -250,14 +252,16 @@ static int sn95031_vhs_event(struct snd_soc_dapm_widget *w,
|
|||
static int sn95031_vihf_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n");
|
||||
/* power up the rail */
|
||||
snd_soc_write(w->codec, SN95031_VIHF, 0x27);
|
||||
snd_soc_write(codec, SN95031_VIHF, 0x27);
|
||||
msleep(1);
|
||||
} else if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||
pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n");
|
||||
snd_soc_write(w->codec, SN95031_VIHF, 0x24);
|
||||
snd_soc_write(codec, SN95031_VIHF, 0x24);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -265,6 +269,7 @@ static int sn95031_vihf_event(struct snd_soc_dapm_widget *w,
|
|||
static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
|
@ -273,15 +278,16 @@ static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w,
|
|||
data_dir = BIT(7);
|
||||
}
|
||||
/* program DMIC LDO, clock and set clock */
|
||||
snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
|
||||
snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(0), clk_dir);
|
||||
snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(7), data_dir);
|
||||
snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
|
||||
snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(0), clk_dir);
|
||||
snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(7), data_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
unsigned int ldo = 0, clk_dir = 0, data_dir = 0;
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
|
@ -290,22 +296,23 @@ static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w,
|
|||
data_dir = BIT(1);
|
||||
}
|
||||
/* program DMIC LDO, clock and set clock */
|
||||
snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
|
||||
snd_soc_update_bits(w->codec, SN95031_DMICBUF0123, BIT(2), clk_dir);
|
||||
snd_soc_update_bits(w->codec, SN95031_DMICBUF45, BIT(1), data_dir);
|
||||
snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo);
|
||||
snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(2), clk_dir);
|
||||
snd_soc_update_bits(codec, SN95031_DMICBUF45, BIT(1), data_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *k, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
unsigned int ldo = 0;
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_ON(event))
|
||||
ldo = BIT(7)|BIT(6);
|
||||
|
||||
/* program DMIC LDO */
|
||||
snd_soc_update_bits(w->codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo);
|
||||
snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,11 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <sound/core.h>
|
||||
|
@ -102,6 +105,35 @@ static const struct reg_default sta32x_regs[] = {
|
|||
{ 0x2c, 0x0c },
|
||||
};
|
||||
|
||||
static const struct regmap_range sta32x_write_regs_range[] = {
|
||||
regmap_reg_range(STA32X_CONFA, STA32X_AUTO2),
|
||||
regmap_reg_range(STA32X_C1CFG, STA32X_FDRC2),
|
||||
};
|
||||
|
||||
static const struct regmap_range sta32x_read_regs_range[] = {
|
||||
regmap_reg_range(STA32X_CONFA, STA32X_AUTO2),
|
||||
regmap_reg_range(STA32X_C1CFG, STA32X_FDRC2),
|
||||
};
|
||||
|
||||
static const struct regmap_range sta32x_volatile_regs_range[] = {
|
||||
regmap_reg_range(STA32X_CFADDR2, STA32X_CFUD),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table sta32x_write_regs = {
|
||||
.yes_ranges = sta32x_write_regs_range,
|
||||
.n_yes_ranges = ARRAY_SIZE(sta32x_write_regs_range),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table sta32x_read_regs = {
|
||||
.yes_ranges = sta32x_read_regs_range,
|
||||
.n_yes_ranges = ARRAY_SIZE(sta32x_read_regs_range),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table sta32x_volatile_regs = {
|
||||
.yes_ranges = sta32x_volatile_regs_range,
|
||||
.n_yes_ranges = ARRAY_SIZE(sta32x_volatile_regs_range),
|
||||
};
|
||||
|
||||
/* regulator power supply names */
|
||||
static const char *sta32x_supply_names[] = {
|
||||
"Vdda", /* analog supply, 3.3VV */
|
||||
|
@ -122,6 +154,8 @@ struct sta32x_priv {
|
|||
u32 coef_shadow[STA32X_COEF_COUNT];
|
||||
struct delayed_work watchdog_work;
|
||||
int shutdown;
|
||||
struct gpio_desc *gpiod_nreset;
|
||||
struct mutex coeff_lock;
|
||||
};
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1);
|
||||
|
@ -155,37 +189,32 @@ static const char *sta32x_limiter_release_rate[] = {
|
|||
"0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299",
|
||||
"0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137",
|
||||
"0.0134", "0.0117", "0.0110", "0.0104" };
|
||||
|
||||
static const unsigned int sta32x_limiter_ac_attack_tlv[] = {
|
||||
TLV_DB_RANGE_HEAD(2),
|
||||
static DECLARE_TLV_DB_RANGE(sta32x_limiter_ac_attack_tlv,
|
||||
0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0),
|
||||
8, 16, TLV_DB_SCALE_ITEM(300, 100, 0),
|
||||
};
|
||||
);
|
||||
|
||||
static const unsigned int sta32x_limiter_ac_release_tlv[] = {
|
||||
TLV_DB_RANGE_HEAD(5),
|
||||
static DECLARE_TLV_DB_RANGE(sta32x_limiter_ac_release_tlv,
|
||||
0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
|
||||
1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0),
|
||||
2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0),
|
||||
3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0),
|
||||
8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0),
|
||||
};
|
||||
);
|
||||
|
||||
static const unsigned int sta32x_limiter_drc_attack_tlv[] = {
|
||||
TLV_DB_RANGE_HEAD(3),
|
||||
static DECLARE_TLV_DB_RANGE(sta32x_limiter_drc_attack_tlv,
|
||||
0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0),
|
||||
8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0),
|
||||
14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0),
|
||||
};
|
||||
);
|
||||
|
||||
static const unsigned int sta32x_limiter_drc_release_tlv[] = {
|
||||
TLV_DB_RANGE_HEAD(5),
|
||||
static DECLARE_TLV_DB_RANGE(sta32x_limiter_drc_release_tlv,
|
||||
0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0),
|
||||
1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0),
|
||||
3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0),
|
||||
5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0),
|
||||
13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),
|
||||
};
|
||||
);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(sta32x_drc_ac_enum,
|
||||
STA32X_CONFD, STA32X_CONFD_DRC_SHIFT,
|
||||
|
@ -244,29 +273,42 @@ static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol,
|
|||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
|
||||
int numcoef = kcontrol->private_value >> 16;
|
||||
int index = kcontrol->private_value & 0xffff;
|
||||
unsigned int cfud;
|
||||
int i;
|
||||
unsigned int cfud, val;
|
||||
int i, ret = 0;
|
||||
|
||||
mutex_lock(&sta32x->coeff_lock);
|
||||
|
||||
/* preserve reserved bits in STA32X_CFUD */
|
||||
cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
|
||||
/* chip documentation does not say if the bits are self clearing,
|
||||
* so do it explicitly */
|
||||
snd_soc_write(codec, STA32X_CFUD, cfud);
|
||||
regmap_read(sta32x->regmap, STA32X_CFUD, &cfud);
|
||||
cfud &= 0xf0;
|
||||
/*
|
||||
* chip documentation does not say if the bits are self clearing,
|
||||
* so do it explicitly
|
||||
*/
|
||||
regmap_write(sta32x->regmap, STA32X_CFUD, cfud);
|
||||
|
||||
snd_soc_write(codec, STA32X_CFADDR2, index);
|
||||
if (numcoef == 1)
|
||||
snd_soc_write(codec, STA32X_CFUD, cfud | 0x04);
|
||||
else if (numcoef == 5)
|
||||
snd_soc_write(codec, STA32X_CFUD, cfud | 0x08);
|
||||
else
|
||||
return -EINVAL;
|
||||
for (i = 0; i < 3 * numcoef; i++)
|
||||
ucontrol->value.bytes.data[i] =
|
||||
snd_soc_read(codec, STA32X_B1CF1 + i);
|
||||
regmap_write(sta32x->regmap, STA32X_CFADDR2, index);
|
||||
if (numcoef == 1) {
|
||||
regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x04);
|
||||
} else if (numcoef == 5) {
|
||||
regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x08);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto exit_unlock;
|
||||
}
|
||||
|
||||
return 0;
|
||||
for (i = 0; i < 3 * numcoef; i++) {
|
||||
regmap_read(sta32x->regmap, STA32X_B1CF1 + i, &val);
|
||||
ucontrol->value.bytes.data[i] = val;
|
||||
}
|
||||
|
||||
exit_unlock:
|
||||
mutex_unlock(&sta32x->coeff_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
|
||||
|
@ -280,24 +322,27 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol,
|
|||
int i;
|
||||
|
||||
/* preserve reserved bits in STA32X_CFUD */
|
||||
cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
|
||||
/* chip documentation does not say if the bits are self clearing,
|
||||
* so do it explicitly */
|
||||
snd_soc_write(codec, STA32X_CFUD, cfud);
|
||||
regmap_read(sta32x->regmap, STA32X_CFUD, &cfud);
|
||||
cfud &= 0xf0;
|
||||
/*
|
||||
* chip documentation does not say if the bits are self clearing,
|
||||
* so do it explicitly
|
||||
*/
|
||||
regmap_write(sta32x->regmap, STA32X_CFUD, cfud);
|
||||
|
||||
snd_soc_write(codec, STA32X_CFADDR2, index);
|
||||
regmap_write(sta32x->regmap, STA32X_CFADDR2, index);
|
||||
for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++)
|
||||
sta32x->coef_shadow[index + i] =
|
||||
(ucontrol->value.bytes.data[3 * i] << 16)
|
||||
| (ucontrol->value.bytes.data[3 * i + 1] << 8)
|
||||
| (ucontrol->value.bytes.data[3 * i + 2]);
|
||||
for (i = 0; i < 3 * numcoef; i++)
|
||||
snd_soc_write(codec, STA32X_B1CF1 + i,
|
||||
ucontrol->value.bytes.data[i]);
|
||||
regmap_write(sta32x->regmap, STA32X_B1CF1 + i,
|
||||
ucontrol->value.bytes.data[i]);
|
||||
if (numcoef == 1)
|
||||
snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
|
||||
regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x01);
|
||||
else if (numcoef == 5)
|
||||
snd_soc_write(codec, STA32X_CFUD, cfud | 0x02);
|
||||
regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x02);
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -311,20 +356,23 @@ static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec)
|
|||
int i;
|
||||
|
||||
/* preserve reserved bits in STA32X_CFUD */
|
||||
cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0;
|
||||
regmap_read(sta32x->regmap, STA32X_CFUD, &cfud);
|
||||
cfud &= 0xf0;
|
||||
|
||||
for (i = 0; i < STA32X_COEF_COUNT; i++) {
|
||||
snd_soc_write(codec, STA32X_CFADDR2, i);
|
||||
snd_soc_write(codec, STA32X_B1CF1,
|
||||
(sta32x->coef_shadow[i] >> 16) & 0xff);
|
||||
snd_soc_write(codec, STA32X_B1CF2,
|
||||
(sta32x->coef_shadow[i] >> 8) & 0xff);
|
||||
snd_soc_write(codec, STA32X_B1CF3,
|
||||
(sta32x->coef_shadow[i]) & 0xff);
|
||||
/* chip documentation does not say if the bits are
|
||||
* self-clearing, so do it explicitly */
|
||||
snd_soc_write(codec, STA32X_CFUD, cfud);
|
||||
snd_soc_write(codec, STA32X_CFUD, cfud | 0x01);
|
||||
regmap_write(sta32x->regmap, STA32X_CFADDR2, i);
|
||||
regmap_write(sta32x->regmap, STA32X_B1CF1,
|
||||
(sta32x->coef_shadow[i] >> 16) & 0xff);
|
||||
regmap_write(sta32x->regmap, STA32X_B1CF2,
|
||||
(sta32x->coef_shadow[i] >> 8) & 0xff);
|
||||
regmap_write(sta32x->regmap, STA32X_B1CF3,
|
||||
(sta32x->coef_shadow[i]) & 0xff);
|
||||
/*
|
||||
* chip documentation does not say if the bits are
|
||||
* self-clearing, so do it explicitly
|
||||
*/
|
||||
regmap_write(sta32x->regmap, STA32X_CFUD, cfud);
|
||||
regmap_write(sta32x->regmap, STA32X_CFUD, cfud | 0x01);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -336,11 +384,11 @@ static int sta32x_cache_sync(struct snd_soc_codec *codec)
|
|||
int rc;
|
||||
|
||||
/* mute during register sync */
|
||||
mute = snd_soc_read(codec, STA32X_MMUTE);
|
||||
snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
|
||||
regmap_read(sta32x->regmap, STA32X_MMUTE, &mute);
|
||||
regmap_write(sta32x->regmap, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
|
||||
sta32x_sync_coef_shadow(codec);
|
||||
rc = regcache_sync(sta32x->regmap);
|
||||
snd_soc_write(codec, STA32X_MMUTE, mute);
|
||||
regmap_write(sta32x->regmap, STA32X_MMUTE, mute);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -508,17 +556,12 @@ static struct {
|
|||
};
|
||||
|
||||
/* MCLK to fs clock ratios */
|
||||
static struct {
|
||||
int ratio;
|
||||
int mcs;
|
||||
} mclk_ratios[3][7] = {
|
||||
{ { 768, 0 }, { 512, 1 }, { 384, 2 }, { 256, 3 },
|
||||
{ 128, 4 }, { 576, 5 }, { 0, 0 } },
|
||||
{ { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } },
|
||||
{ { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } },
|
||||
static int mcs_ratio_table[3][7] = {
|
||||
{ 768, 512, 384, 256, 128, 576, 0 },
|
||||
{ 384, 256, 192, 128, 64, 0 },
|
||||
{ 384, 256, 192, 128, 64, 0 },
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* sta32x_set_dai_sysclk - configure MCLK
|
||||
* @codec_dai: the codec DAI
|
||||
|
@ -543,46 +586,10 @@ static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
|||
{
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
|
||||
int i, j, ir, fs;
|
||||
unsigned int rates = 0;
|
||||
unsigned int rate_min = -1;
|
||||
unsigned int rate_max = 0;
|
||||
|
||||
pr_debug("mclk=%u\n", freq);
|
||||
dev_dbg(codec->dev, "mclk=%u\n", freq);
|
||||
sta32x->mclk = freq;
|
||||
|
||||
if (sta32x->mclk) {
|
||||
for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {
|
||||
ir = interpolation_ratios[i].ir;
|
||||
fs = interpolation_ratios[i].fs;
|
||||
for (j = 0; mclk_ratios[ir][j].ratio; j++) {
|
||||
if (mclk_ratios[ir][j].ratio * fs == freq) {
|
||||
rates |= snd_pcm_rate_to_rate_bit(fs);
|
||||
if (fs < rate_min)
|
||||
rate_min = fs;
|
||||
if (fs > rate_max)
|
||||
rate_max = fs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* FIXME: soc should support a rate list */
|
||||
rates &= ~SNDRV_PCM_RATE_KNOT;
|
||||
|
||||
if (!rates) {
|
||||
dev_err(codec->dev, "could not find a valid sample rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
/* enable all possible rates */
|
||||
rates = STA32X_RATES;
|
||||
rate_min = 32000;
|
||||
rate_max = 192000;
|
||||
}
|
||||
|
||||
codec_dai->driver->playback.rates = rates;
|
||||
codec_dai->driver->playback.rate_min = rate_min;
|
||||
codec_dai->driver->playback.rate_max = rate_max;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -599,10 +606,7 @@ static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
|||
{
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
|
||||
u8 confb = snd_soc_read(codec, STA32X_CONFB);
|
||||
|
||||
pr_debug("\n");
|
||||
confb &= ~(STA32X_CONFB_C1IM | STA32X_CONFB_C2IM);
|
||||
u8 confb = 0;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
|
@ -632,8 +636,8 @@ static int sta32x_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_soc_write(codec, STA32X_CONFB, confb);
|
||||
return 0;
|
||||
return regmap_update_bits(sta32x->regmap, STA32X_CONFB,
|
||||
STA32X_CONFB_C1IM | STA32X_CONFB_C2IM, confb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -651,39 +655,55 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int rate;
|
||||
int i, mcs = -1, ir = -1;
|
||||
u8 confa, confb;
|
||||
int i, mcs = -EINVAL, ir = -EINVAL;
|
||||
unsigned int confa, confb;
|
||||
unsigned int rate, ratio;
|
||||
int ret;
|
||||
|
||||
if (!sta32x->mclk) {
|
||||
dev_err(codec->dev,
|
||||
"sta32x->mclk is unset. Unable to determine ratio\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rate = params_rate(params);
|
||||
pr_debug("rate: %u\n", rate);
|
||||
for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++)
|
||||
ratio = sta32x->mclk / rate;
|
||||
dev_dbg(codec->dev, "rate: %u, ratio: %u\n", rate, ratio);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) {
|
||||
if (interpolation_ratios[i].fs == rate) {
|
||||
ir = interpolation_ratios[i].ir;
|
||||
break;
|
||||
}
|
||||
if (ir < 0)
|
||||
}
|
||||
|
||||
if (ir < 0) {
|
||||
dev_err(codec->dev, "Unsupported samplerate: %u\n", rate);
|
||||
return -EINVAL;
|
||||
for (i = 0; mclk_ratios[ir][i].ratio; i++)
|
||||
if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) {
|
||||
mcs = mclk_ratios[ir][i].mcs;
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (mcs_ratio_table[ir][i] == ratio) {
|
||||
mcs = i;
|
||||
break;
|
||||
}
|
||||
if (mcs < 0)
|
||||
}
|
||||
|
||||
if (mcs < 0) {
|
||||
dev_err(codec->dev, "Unresolvable ratio: %u\n", ratio);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
confa = snd_soc_read(codec, STA32X_CONFA);
|
||||
confa &= ~(STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK);
|
||||
confa |= (ir << STA32X_CONFA_IR_SHIFT) | (mcs << STA32X_CONFA_MCS_SHIFT);
|
||||
confa = (ir << STA32X_CONFA_IR_SHIFT) |
|
||||
(mcs << STA32X_CONFA_MCS_SHIFT);
|
||||
confb = 0;
|
||||
|
||||
confb = snd_soc_read(codec, STA32X_CONFB);
|
||||
confb &= ~(STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB);
|
||||
switch (params_width(params)) {
|
||||
case 24:
|
||||
pr_debug("24bit\n");
|
||||
dev_dbg(codec->dev, "24bit\n");
|
||||
/* fall through */
|
||||
case 32:
|
||||
pr_debug("24bit or 32bit\n");
|
||||
dev_dbg(codec->dev, "24bit or 32bit\n");
|
||||
switch (sta32x->format) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
confb |= 0x0;
|
||||
|
@ -698,7 +718,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
break;
|
||||
case 20:
|
||||
pr_debug("20bit\n");
|
||||
dev_dbg(codec->dev, "20bit\n");
|
||||
switch (sta32x->format) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
confb |= 0x4;
|
||||
|
@ -713,7 +733,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
break;
|
||||
case 18:
|
||||
pr_debug("18bit\n");
|
||||
dev_dbg(codec->dev, "18bit\n");
|
||||
switch (sta32x->format) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
confb |= 0x8;
|
||||
|
@ -728,7 +748,7 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
break;
|
||||
case 16:
|
||||
pr_debug("16bit\n");
|
||||
dev_dbg(codec->dev, "16bit\n");
|
||||
switch (sta32x->format) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
confb |= 0x0;
|
||||
|
@ -746,8 +766,30 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_soc_write(codec, STA32X_CONFA, confa);
|
||||
snd_soc_write(codec, STA32X_CONFB, confb);
|
||||
ret = regmap_update_bits(sta32x->regmap, STA32X_CONFA,
|
||||
STA32X_CONFA_MCS_MASK | STA32X_CONFA_IR_MASK,
|
||||
confa);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(sta32x->regmap, STA32X_CONFB,
|
||||
STA32X_CONFB_SAI_MASK | STA32X_CONFB_SAIFB,
|
||||
confb);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sta32x_startup_sequence(struct sta32x_priv *sta32x)
|
||||
{
|
||||
if (sta32x->gpiod_nreset) {
|
||||
gpiod_set_value(sta32x->gpiod_nreset, 0);
|
||||
mdelay(1);
|
||||
gpiod_set_value(sta32x->gpiod_nreset, 1);
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -766,14 +808,14 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
|
|||
int ret;
|
||||
struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
pr_debug("level = %d\n", level);
|
||||
dev_dbg(codec->dev, "level = %d\n", level);
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
/* Full power on */
|
||||
snd_soc_update_bits(codec, STA32X_CONFF,
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFF,
|
||||
STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
|
||||
STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);
|
||||
break;
|
||||
|
@ -788,25 +830,28 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec,
|
|||
return ret;
|
||||
}
|
||||
|
||||
sta32x_startup_sequence(sta32x);
|
||||
sta32x_cache_sync(codec);
|
||||
sta32x_watchdog_start(sta32x);
|
||||
}
|
||||
|
||||
/* Power up to mute */
|
||||
/* FIXME */
|
||||
snd_soc_update_bits(codec, STA32X_CONFF,
|
||||
STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
|
||||
STA32X_CONFF_PWDN | STA32X_CONFF_EAPD);
|
||||
/* Power down */
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFF,
|
||||
STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
|
||||
0);
|
||||
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_OFF:
|
||||
/* The chip runs through the power down sequence for us. */
|
||||
snd_soc_update_bits(codec, STA32X_CONFF,
|
||||
STA32X_CONFF_PWDN | STA32X_CONFF_EAPD,
|
||||
STA32X_CONFF_PWDN);
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFF,
|
||||
STA32X_CONFF_PWDN | STA32X_CONFF_EAPD, 0);
|
||||
msleep(300);
|
||||
sta32x_watchdog_stop(sta32x);
|
||||
|
||||
if (sta32x->gpiod_nreset)
|
||||
gpiod_set_value(sta32x->gpiod_nreset, 0);
|
||||
|
||||
regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies),
|
||||
sta32x->supplies);
|
||||
break;
|
||||
|
@ -822,7 +867,7 @@ static const struct snd_soc_dai_ops sta32x_dai_ops = {
|
|||
};
|
||||
|
||||
static struct snd_soc_dai_driver sta32x_dai = {
|
||||
.name = "STA32X",
|
||||
.name = "sta32x-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
|
@ -836,11 +881,8 @@ static struct snd_soc_dai_driver sta32x_dai = {
|
|||
static int sta32x_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
|
||||
struct sta32x_platform_data *pdata = sta32x->pdata;
|
||||
int i, ret = 0, thermal = 0;
|
||||
|
||||
sta32x->codec = codec;
|
||||
sta32x->pdata = dev_get_platdata(codec->dev);
|
||||
|
||||
ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
|
||||
sta32x->supplies);
|
||||
if (ret != 0) {
|
||||
|
@ -848,50 +890,73 @@ static int sta32x_probe(struct snd_soc_codec *codec)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Chip documentation explicitly requires that the reset values
|
||||
* of reserved register bits are left untouched.
|
||||
* Write the register default value to cache for reserved registers,
|
||||
* so the write to the these registers are suppressed by the cache
|
||||
* restore code when it skips writes of default registers.
|
||||
*/
|
||||
regcache_cache_only(sta32x->regmap, true);
|
||||
snd_soc_write(codec, STA32X_CONFC, 0xc2);
|
||||
snd_soc_write(codec, STA32X_CONFE, 0xc2);
|
||||
snd_soc_write(codec, STA32X_CONFF, 0x5c);
|
||||
snd_soc_write(codec, STA32X_MMUTE, 0x10);
|
||||
snd_soc_write(codec, STA32X_AUTO1, 0x60);
|
||||
snd_soc_write(codec, STA32X_AUTO3, 0x00);
|
||||
snd_soc_write(codec, STA32X_C3CFG, 0x40);
|
||||
regcache_cache_only(sta32x->regmap, false);
|
||||
ret = sta32x_startup_sequence(sta32x);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "Failed to startup device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set thermal warning adjustment and recovery */
|
||||
if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE))
|
||||
/* CONFA */
|
||||
if (!pdata->thermal_warning_recovery)
|
||||
thermal |= STA32X_CONFA_TWAB;
|
||||
if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_RECOVERY_ENABLE))
|
||||
if (!pdata->thermal_warning_adjustment)
|
||||
thermal |= STA32X_CONFA_TWRB;
|
||||
snd_soc_update_bits(codec, STA32X_CONFA,
|
||||
STA32X_CONFA_TWAB | STA32X_CONFA_TWRB,
|
||||
thermal);
|
||||
if (!pdata->fault_detect_recovery)
|
||||
thermal |= STA32X_CONFA_FDRB;
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFA,
|
||||
STA32X_CONFA_TWAB | STA32X_CONFA_TWRB |
|
||||
STA32X_CONFA_FDRB,
|
||||
thermal);
|
||||
|
||||
/* CONFC */
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFC,
|
||||
STA32X_CONFC_CSZ_MASK,
|
||||
pdata->drop_compensation_ns
|
||||
<< STA32X_CONFC_CSZ_SHIFT);
|
||||
|
||||
/* CONFE */
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFE,
|
||||
STA32X_CONFE_MPCV,
|
||||
pdata->max_power_use_mpcc ?
|
||||
STA32X_CONFE_MPCV : 0);
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFE,
|
||||
STA32X_CONFE_MPC,
|
||||
pdata->max_power_correction ?
|
||||
STA32X_CONFE_MPC : 0);
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFE,
|
||||
STA32X_CONFE_AME,
|
||||
pdata->am_reduction_mode ?
|
||||
STA32X_CONFE_AME : 0);
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFE,
|
||||
STA32X_CONFE_PWMS,
|
||||
pdata->odd_pwm_speed_mode ?
|
||||
STA32X_CONFE_PWMS : 0);
|
||||
|
||||
/* CONFF */
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFF,
|
||||
STA32X_CONFF_IDE,
|
||||
pdata->invalid_input_detect_mute ?
|
||||
STA32X_CONFF_IDE : 0);
|
||||
|
||||
/* select output configuration */
|
||||
snd_soc_update_bits(codec, STA32X_CONFF,
|
||||
STA32X_CONFF_OCFG_MASK,
|
||||
sta32x->pdata->output_conf
|
||||
<< STA32X_CONFF_OCFG_SHIFT);
|
||||
regmap_update_bits(sta32x->regmap, STA32X_CONFF,
|
||||
STA32X_CONFF_OCFG_MASK,
|
||||
pdata->output_conf
|
||||
<< STA32X_CONFF_OCFG_SHIFT);
|
||||
|
||||
/* channel to output mapping */
|
||||
snd_soc_update_bits(codec, STA32X_C1CFG,
|
||||
STA32X_CxCFG_OM_MASK,
|
||||
sta32x->pdata->ch1_output_mapping
|
||||
<< STA32X_CxCFG_OM_SHIFT);
|
||||
snd_soc_update_bits(codec, STA32X_C2CFG,
|
||||
STA32X_CxCFG_OM_MASK,
|
||||
sta32x->pdata->ch2_output_mapping
|
||||
<< STA32X_CxCFG_OM_SHIFT);
|
||||
snd_soc_update_bits(codec, STA32X_C3CFG,
|
||||
STA32X_CxCFG_OM_MASK,
|
||||
sta32x->pdata->ch3_output_mapping
|
||||
<< STA32X_CxCFG_OM_SHIFT);
|
||||
regmap_update_bits(sta32x->regmap, STA32X_C1CFG,
|
||||
STA32X_CxCFG_OM_MASK,
|
||||
pdata->ch1_output_mapping
|
||||
<< STA32X_CxCFG_OM_SHIFT);
|
||||
regmap_update_bits(sta32x->regmap, STA32X_C2CFG,
|
||||
STA32X_CxCFG_OM_MASK,
|
||||
pdata->ch2_output_mapping
|
||||
<< STA32X_CxCFG_OM_SHIFT);
|
||||
regmap_update_bits(sta32x->regmap, STA32X_C3CFG,
|
||||
STA32X_CxCFG_OM_MASK,
|
||||
pdata->ch3_output_mapping
|
||||
<< STA32X_CxCFG_OM_SHIFT);
|
||||
|
||||
/* initialize coefficient shadow RAM with reset values */
|
||||
for (i = 4; i <= 49; i += 5)
|
||||
|
@ -924,16 +989,6 @@ static int sta32x_remove(struct snd_soc_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool sta32x_reg_is_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case STA32X_CONFA ... STA32X_L2ATRT:
|
||||
case STA32X_MPCC1 ... STA32X_FDRC2:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct snd_soc_codec_driver sta32x_codec = {
|
||||
.probe = sta32x_probe,
|
||||
.remove = sta32x_remove,
|
||||
|
@ -954,12 +1009,75 @@ static const struct regmap_config sta32x_regmap = {
|
|||
.reg_defaults = sta32x_regs,
|
||||
.num_reg_defaults = ARRAY_SIZE(sta32x_regs),
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_reg = sta32x_reg_is_volatile,
|
||||
.wr_table = &sta32x_write_regs,
|
||||
.rd_table = &sta32x_read_regs,
|
||||
.volatile_table = &sta32x_volatile_regs,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id st32x_dt_ids[] = {
|
||||
{ .compatible = "st,sta32x", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, st32x_dt_ids);
|
||||
|
||||
static int sta32x_probe_dt(struct device *dev, struct sta32x_priv *sta32x)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
struct sta32x_platform_data *pdata;
|
||||
u16 tmp;
|
||||
|
||||
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
of_property_read_u8(np, "st,output-conf",
|
||||
&pdata->output_conf);
|
||||
of_property_read_u8(np, "st,ch1-output-mapping",
|
||||
&pdata->ch1_output_mapping);
|
||||
of_property_read_u8(np, "st,ch2-output-mapping",
|
||||
&pdata->ch2_output_mapping);
|
||||
of_property_read_u8(np, "st,ch3-output-mapping",
|
||||
&pdata->ch3_output_mapping);
|
||||
|
||||
if (of_get_property(np, "st,thermal-warning-recovery", NULL))
|
||||
pdata->thermal_warning_recovery = 1;
|
||||
if (of_get_property(np, "st,thermal-warning-adjustment", NULL))
|
||||
pdata->thermal_warning_adjustment = 1;
|
||||
if (of_get_property(np, "st,needs_esd_watchdog", NULL))
|
||||
pdata->needs_esd_watchdog = 1;
|
||||
|
||||
tmp = 140;
|
||||
of_property_read_u16(np, "st,drop-compensation-ns", &tmp);
|
||||
pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20;
|
||||
|
||||
/* CONFE */
|
||||
if (of_get_property(np, "st,max-power-use-mpcc", NULL))
|
||||
pdata->max_power_use_mpcc = 1;
|
||||
|
||||
if (of_get_property(np, "st,max-power-correction", NULL))
|
||||
pdata->max_power_correction = 1;
|
||||
|
||||
if (of_get_property(np, "st,am-reduction-mode", NULL))
|
||||
pdata->am_reduction_mode = 1;
|
||||
|
||||
if (of_get_property(np, "st,odd-pwm-speed-mode", NULL))
|
||||
pdata->odd_pwm_speed_mode = 1;
|
||||
|
||||
/* CONFF */
|
||||
if (of_get_property(np, "st,invalid-input-detect-mute", NULL))
|
||||
pdata->invalid_input_detect_mute = 1;
|
||||
|
||||
sta32x->pdata = pdata;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sta32x_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct device *dev = &i2c->dev;
|
||||
struct sta32x_priv *sta32x;
|
||||
int ret, i;
|
||||
|
||||
|
@ -968,6 +1086,29 @@ static int sta32x_i2c_probe(struct i2c_client *i2c,
|
|||
if (!sta32x)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&sta32x->coeff_lock);
|
||||
sta32x->pdata = dev_get_platdata(dev);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
if (dev->of_node) {
|
||||
ret = sta32x_probe_dt(dev, sta32x);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* GPIOs */
|
||||
sta32x->gpiod_nreset = devm_gpiod_get(dev, "reset");
|
||||
if (IS_ERR(sta32x->gpiod_nreset)) {
|
||||
ret = PTR_ERR(sta32x->gpiod_nreset);
|
||||
if (ret != -ENOENT && ret != -ENOSYS)
|
||||
return ret;
|
||||
|
||||
sta32x->gpiod_nreset = NULL;
|
||||
} else {
|
||||
gpiod_direction_output(sta32x->gpiod_nreset, 0);
|
||||
}
|
||||
|
||||
/* regulators */
|
||||
for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
|
||||
sta32x->supplies[i].supply = sta32x_supply_names[i];
|
||||
|
@ -982,15 +1123,15 @@ static int sta32x_i2c_probe(struct i2c_client *i2c,
|
|||
sta32x->regmap = devm_regmap_init_i2c(i2c, &sta32x_regmap);
|
||||
if (IS_ERR(sta32x->regmap)) {
|
||||
ret = PTR_ERR(sta32x->regmap);
|
||||
dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
|
||||
dev_err(dev, "Failed to init regmap: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(i2c, sta32x);
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
|
||||
if (ret != 0)
|
||||
dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret);
|
||||
ret = snd_soc_register_codec(dev, &sta32x_codec, &sta32x_dai, 1);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "Failed to register codec (%d)\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1013,6 +1154,7 @@ static struct i2c_driver sta32x_i2c_driver = {
|
|||
.driver = {
|
||||
.name = "sta32x",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(st32x_dt_ids),
|
||||
},
|
||||
.probe = sta32x_i2c_probe,
|
||||
.remove = sta32x_i2c_remove,
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
#define STA32X_CONFF_OCFG_MASK 0x03
|
||||
#define STA32X_CONFF_OCFG_SHIFT 0
|
||||
#define STA32X_CONFF_IDE 0x04
|
||||
#define STA32X_CONFF_IDE_SHIFT 3
|
||||
#define STA32X_CONFF_IDE_SHIFT 2
|
||||
#define STA32X_CONFF_BCLE 0x08
|
||||
#define STA32X_CONFF_ECLE 0x20
|
||||
#define STA32X_CONFF_PWDN 0x40
|
||||
|
|
|
@ -349,7 +349,8 @@ static int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg,
|
|||
static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int reg = AIC31XX_DACFLAG1;
|
||||
unsigned int mask;
|
||||
|
||||
|
@ -377,7 +378,7 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
|
|||
reg = AIC31XX_ADCFLAG;
|
||||
break;
|
||||
default:
|
||||
dev_err(w->codec->dev, "Unknown widget '%s' calling %s\n",
|
||||
dev_err(codec->dev, "Unknown widget '%s' calling %s\n",
|
||||
w->name, __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -388,7 +389,7 @@ static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w,
|
|||
case SND_SOC_DAPM_POST_PMD:
|
||||
return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100);
|
||||
default:
|
||||
dev_dbg(w->codec->dev,
|
||||
dev_dbg(codec->dev,
|
||||
"Unhandled dapm widget event %d from %s\n",
|
||||
event, w->name);
|
||||
}
|
||||
|
@ -433,7 +434,7 @@ static const struct snd_kcontrol_new aic31xx_dapm_spr_switch =
|
|||
static int mic_bias_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
|
|
@ -87,6 +87,7 @@ struct aic3x_priv {
|
|||
#define AIC3X_MODEL_3X 0
|
||||
#define AIC3X_MODEL_33 1
|
||||
#define AIC3X_MODEL_3007 2
|
||||
#define AIC3X_MODEL_3104 3
|
||||
u16 model;
|
||||
|
||||
/* Selects the micbias voltage */
|
||||
|
@ -197,7 +198,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
|
|||
static int mic_bias_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -316,52 +317,37 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
|
|||
* only for swapped L-to-R and R-to-L routes. See below stereo controls
|
||||
* for direct L-to-L and R-to-R routes.
|
||||
*/
|
||||
SOC_SINGLE_TLV("Left Line Mixer Line2R Bypass Volume",
|
||||
LINE2R_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Left Line Mixer PGAR Bypass Volume",
|
||||
PGAR_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Left Line Mixer DACR1 Playback Volume",
|
||||
DACR1_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Right Line Mixer Line2L Bypass Volume",
|
||||
LINE2L_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Right Line Mixer PGAL Bypass Volume",
|
||||
PGAL_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Right Line Mixer DACL1 Playback Volume",
|
||||
DACL1_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Left HP Mixer Line2R Bypass Volume",
|
||||
LINE2R_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Left HP Mixer PGAR Bypass Volume",
|
||||
PGAR_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Left HP Mixer DACR1 Playback Volume",
|
||||
DACR1_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Right HP Mixer Line2L Bypass Volume",
|
||||
LINE2L_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Right HP Mixer PGAL Bypass Volume",
|
||||
PGAL_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Right HP Mixer DACL1 Playback Volume",
|
||||
DACL1_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Left HPCOM Mixer Line2R Bypass Volume",
|
||||
LINE2R_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Left HPCOM Mixer PGAR Bypass Volume",
|
||||
PGAR_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Left HPCOM Mixer DACR1 Playback Volume",
|
||||
DACR1_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Right HPCOM Mixer Line2L Bypass Volume",
|
||||
LINE2L_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Right HPCOM Mixer PGAL Bypass Volume",
|
||||
PGAL_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
SOC_SINGLE_TLV("Right HPCOM Mixer DACL1 Playback Volume",
|
||||
DACL1_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
/* Stereo output controls for direct L-to-L and R-to-R routes */
|
||||
SOC_DOUBLE_R_TLV("Line Line2 Bypass Volume",
|
||||
LINE2L_2_LLOPM_VOL, LINE2R_2_RLOPM_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
SOC_DOUBLE_R_TLV("Line PGA Bypass Volume",
|
||||
PGAL_2_LLOPM_VOL, PGAR_2_RLOPM_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
|
@ -369,9 +355,6 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
|
|||
DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_DOUBLE_R_TLV("HP Line2 Bypass Volume",
|
||||
LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
SOC_DOUBLE_R_TLV("HP PGA Bypass Volume",
|
||||
PGAL_2_HPLOUT_VOL, PGAR_2_HPROUT_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
|
@ -379,9 +362,6 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
|
|||
DACL1_2_HPLOUT_VOL, DACR1_2_HPROUT_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Volume",
|
||||
LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
SOC_DOUBLE_R_TLV("HPCOM PGA Bypass Volume",
|
||||
PGAL_2_HPLCOM_VOL, PGAR_2_HPRCOM_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
|
@ -424,6 +404,45 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
|
|||
SOC_ENUM("Output Driver Ramp-up step", aic3x_rampup_step_enum),
|
||||
};
|
||||
|
||||
/* For other than tlv320aic3104 */
|
||||
static const struct snd_kcontrol_new aic3x_extra_snd_controls[] = {
|
||||
/*
|
||||
* Output controls that map to output mixer switches. Note these are
|
||||
* only for swapped L-to-R and R-to-L routes. See below stereo controls
|
||||
* for direct L-to-L and R-to-R routes.
|
||||
*/
|
||||
SOC_SINGLE_TLV("Left Line Mixer Line2R Bypass Volume",
|
||||
LINE2R_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Right Line Mixer Line2L Bypass Volume",
|
||||
LINE2L_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Left HP Mixer Line2R Bypass Volume",
|
||||
LINE2R_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Right HP Mixer Line2L Bypass Volume",
|
||||
LINE2L_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Left HPCOM Mixer Line2R Bypass Volume",
|
||||
LINE2R_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_SINGLE_TLV("Right HPCOM Mixer Line2L Bypass Volume",
|
||||
LINE2L_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
|
||||
|
||||
/* Stereo output controls for direct L-to-L and R-to-R routes */
|
||||
SOC_DOUBLE_R_TLV("Line Line2 Bypass Volume",
|
||||
LINE2L_2_LLOPM_VOL, LINE2R_2_RLOPM_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_DOUBLE_R_TLV("HP Line2 Bypass Volume",
|
||||
LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
|
||||
SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Volume",
|
||||
LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL,
|
||||
0, 118, 1, output_stage_tlv),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new aic3x_mono_controls[] = {
|
||||
SOC_DOUBLE_R_TLV("Mono Line2 Bypass Volume",
|
||||
LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL,
|
||||
|
@ -464,22 +483,24 @@ SOC_DAPM_ENUM("Route", aic3x_right_hpcom_enum);
|
|||
|
||||
/* Left Line Mixer */
|
||||
static const struct snd_kcontrol_new aic3x_left_line_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_LLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_LLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_LLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_LLOPM_VOL, 7, 1, 0),
|
||||
/* Not on tlv320aic3104 */
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0),
|
||||
};
|
||||
|
||||
/* Right Line Mixer */
|
||||
static const struct snd_kcontrol_new aic3x_right_line_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_RLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_RLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_RLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_RLOPM_VOL, 7, 1, 0),
|
||||
/* Not on tlv320aic3104 */
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
|
||||
};
|
||||
|
||||
/* Mono Mixer */
|
||||
|
@ -494,42 +515,46 @@ static const struct snd_kcontrol_new aic3x_mono_mixer_controls[] = {
|
|||
|
||||
/* Left HP Mixer */
|
||||
static const struct snd_kcontrol_new aic3x_left_hp_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLOUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLOUT_VOL, 7, 1, 0),
|
||||
/* Not on tlv320aic3104 */
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLOUT_VOL, 7, 1, 0),
|
||||
};
|
||||
|
||||
/* Right HP Mixer */
|
||||
static const struct snd_kcontrol_new aic3x_right_hp_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPROUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPROUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPROUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPROUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPROUT_VOL, 7, 1, 0),
|
||||
/* Not on tlv320aic3104 */
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPROUT_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0),
|
||||
};
|
||||
|
||||
/* Left HPCOM Mixer */
|
||||
static const struct snd_kcontrol_new aic3x_left_hpcom_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLCOM_VOL, 7, 1, 0),
|
||||
/* Not on tlv320aic3104 */
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLCOM_VOL, 7, 1, 0),
|
||||
};
|
||||
|
||||
/* Right HPCOM Mixer */
|
||||
static const struct snd_kcontrol_new aic3x_right_hpcom_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPRCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPRCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0),
|
||||
/* Not on tlv320aic3104 */
|
||||
SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPRCOM_VOL, 7, 1, 0),
|
||||
SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
|
||||
};
|
||||
|
||||
/* Left PGA Mixer */
|
||||
|
@ -550,6 +575,22 @@ static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = {
|
|||
SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1),
|
||||
};
|
||||
|
||||
/* Left PGA Mixer for tlv320aic3104 */
|
||||
static const struct snd_kcontrol_new aic3104_left_pga_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1),
|
||||
SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_LADC_CTRL, 3, 1, 1),
|
||||
SOC_DAPM_SINGLE_AIC3X("Mic2L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1),
|
||||
SOC_DAPM_SINGLE_AIC3X("Mic2R Switch", MIC3LR_2_LADC_CTRL, 0, 1, 1),
|
||||
};
|
||||
|
||||
/* Right PGA Mixer for tlv320aic3104 */
|
||||
static const struct snd_kcontrol_new aic3104_right_pga_mixer_controls[] = {
|
||||
SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1),
|
||||
SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_RADC_CTRL, 3, 1, 1),
|
||||
SOC_DAPM_SINGLE_AIC3X("Mic2L Switch", MIC3LR_2_RADC_CTRL, 4, 1, 1),
|
||||
SOC_DAPM_SINGLE_AIC3X("Mic2R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1),
|
||||
};
|
||||
|
||||
/* Left Line1 Mux */
|
||||
static const struct snd_kcontrol_new aic3x_left_line1l_mux_controls =
|
||||
SOC_DAPM_ENUM("Route", aic3x_line1l_2_l_enum);
|
||||
|
@ -593,26 +634,56 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
|
|||
|
||||
/* Inputs to Left ADC */
|
||||
SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0),
|
||||
SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_left_pga_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_left_pga_mixer_controls)),
|
||||
SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_left_line1l_mux_controls),
|
||||
SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_left_line1r_mux_controls),
|
||||
SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_left_line2_mux_controls),
|
||||
|
||||
/* Inputs to Right ADC */
|
||||
SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
|
||||
LINE1R_2_RADC_CTRL, 2, 0),
|
||||
SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_right_pga_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_right_pga_mixer_controls)),
|
||||
SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_right_line1l_mux_controls),
|
||||
SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_right_line1r_mux_controls),
|
||||
|
||||
/* Mic Bias */
|
||||
SND_SOC_DAPM_SUPPLY("Mic Bias", MICBIAS_CTRL, 6, 0,
|
||||
mic_bias_event,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("LLOUT"),
|
||||
SND_SOC_DAPM_OUTPUT("RLOUT"),
|
||||
SND_SOC_DAPM_OUTPUT("HPLOUT"),
|
||||
SND_SOC_DAPM_OUTPUT("HPROUT"),
|
||||
SND_SOC_DAPM_OUTPUT("HPLCOM"),
|
||||
SND_SOC_DAPM_OUTPUT("HPRCOM"),
|
||||
|
||||
SND_SOC_DAPM_INPUT("LINE1L"),
|
||||
SND_SOC_DAPM_INPUT("LINE1R"),
|
||||
|
||||
/*
|
||||
* Virtual output pin to detection block inside codec. This can be
|
||||
* used to keep codec bias on if gpio or detection features are needed.
|
||||
* Force pin on or construct a path with an input jack and mic bias
|
||||
* widgets.
|
||||
*/
|
||||
SND_SOC_DAPM_OUTPUT("Detection"),
|
||||
};
|
||||
|
||||
/* For other than tlv320aic3104 */
|
||||
static const struct snd_soc_dapm_widget aic3x_extra_dapm_widgets[] = {
|
||||
/* Inputs to Left ADC */
|
||||
SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_left_pga_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_left_pga_mixer_controls)),
|
||||
SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_left_line2_mux_controls),
|
||||
|
||||
/* Inputs to Right ADC */
|
||||
SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_right_pga_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_right_pga_mixer_controls)),
|
||||
SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_right_line2_mux_controls),
|
||||
|
||||
|
@ -637,11 +708,6 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 32",
|
||||
AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0),
|
||||
|
||||
/* Mic Bias */
|
||||
SND_SOC_DAPM_SUPPLY("Mic Bias", MICBIAS_CTRL, 6, 0,
|
||||
mic_bias_event,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
|
||||
|
||||
/* Output mixers */
|
||||
SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_left_line_mixer_controls[0],
|
||||
|
@ -662,27 +728,46 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
|
|||
&aic3x_right_hpcom_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_right_hpcom_mixer_controls)),
|
||||
|
||||
SND_SOC_DAPM_OUTPUT("LLOUT"),
|
||||
SND_SOC_DAPM_OUTPUT("RLOUT"),
|
||||
SND_SOC_DAPM_OUTPUT("HPLOUT"),
|
||||
SND_SOC_DAPM_OUTPUT("HPROUT"),
|
||||
SND_SOC_DAPM_OUTPUT("HPLCOM"),
|
||||
SND_SOC_DAPM_OUTPUT("HPRCOM"),
|
||||
|
||||
SND_SOC_DAPM_INPUT("MIC3L"),
|
||||
SND_SOC_DAPM_INPUT("MIC3R"),
|
||||
SND_SOC_DAPM_INPUT("LINE1L"),
|
||||
SND_SOC_DAPM_INPUT("LINE1R"),
|
||||
SND_SOC_DAPM_INPUT("LINE2L"),
|
||||
SND_SOC_DAPM_INPUT("LINE2R"),
|
||||
};
|
||||
|
||||
/*
|
||||
* Virtual output pin to detection block inside codec. This can be
|
||||
* used to keep codec bias on if gpio or detection features are needed.
|
||||
* Force pin on or construct a path with an input jack and mic bias
|
||||
* widgets.
|
||||
*/
|
||||
SND_SOC_DAPM_OUTPUT("Detection"),
|
||||
/* For tlv320aic3104 */
|
||||
static const struct snd_soc_dapm_widget aic3104_extra_dapm_widgets[] = {
|
||||
/* Inputs to Left ADC */
|
||||
SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3104_left_pga_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3104_left_pga_mixer_controls)),
|
||||
|
||||
/* Inputs to Right ADC */
|
||||
SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3104_right_pga_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3104_right_pga_mixer_controls)),
|
||||
|
||||
/* Output mixers */
|
||||
SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_left_line_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_left_line_mixer_controls) - 2),
|
||||
SND_SOC_DAPM_MIXER("Right Line Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_right_line_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_right_line_mixer_controls) - 2),
|
||||
SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_left_hp_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_left_hp_mixer_controls) - 2),
|
||||
SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_right_hp_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_right_hp_mixer_controls) - 2),
|
||||
SND_SOC_DAPM_MIXER("Left HPCOM Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_left_hpcom_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_left_hpcom_mixer_controls) - 2),
|
||||
SND_SOC_DAPM_MIXER("Right HPCOM Mixer", SND_SOC_NOPM, 0, 0,
|
||||
&aic3x_right_hpcom_mixer_controls[0],
|
||||
ARRAY_SIZE(aic3x_right_hpcom_mixer_controls) - 2),
|
||||
|
||||
SND_SOC_DAPM_INPUT("MIC2L"),
|
||||
SND_SOC_DAPM_INPUT("MIC2R"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget aic3x_dapm_mono_widgets[] = {
|
||||
|
@ -712,17 +797,10 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
{"Left Line1R Mux", "single-ended", "LINE1R"},
|
||||
{"Left Line1R Mux", "differential", "LINE1R"},
|
||||
|
||||
{"Left Line2L Mux", "single-ended", "LINE2L"},
|
||||
{"Left Line2L Mux", "differential", "LINE2L"},
|
||||
|
||||
{"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"},
|
||||
{"Left PGA Mixer", "Line1R Switch", "Left Line1R Mux"},
|
||||
{"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"},
|
||||
{"Left PGA Mixer", "Mic3L Switch", "MIC3L"},
|
||||
{"Left PGA Mixer", "Mic3R Switch", "MIC3R"},
|
||||
|
||||
{"Left ADC", NULL, "Left PGA Mixer"},
|
||||
{"Left ADC", NULL, "GPIO1 dmic modclk"},
|
||||
|
||||
/* Right Input */
|
||||
{"Right Line1R Mux", "single-ended", "LINE1R"},
|
||||
|
@ -730,25 +808,10 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
{"Right Line1L Mux", "single-ended", "LINE1L"},
|
||||
{"Right Line1L Mux", "differential", "LINE1L"},
|
||||
|
||||
{"Right Line2R Mux", "single-ended", "LINE2R"},
|
||||
{"Right Line2R Mux", "differential", "LINE2R"},
|
||||
|
||||
{"Right PGA Mixer", "Line1L Switch", "Right Line1L Mux"},
|
||||
{"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"},
|
||||
{"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"},
|
||||
{"Right PGA Mixer", "Mic3L Switch", "MIC3L"},
|
||||
{"Right PGA Mixer", "Mic3R Switch", "MIC3R"},
|
||||
|
||||
{"Right ADC", NULL, "Right PGA Mixer"},
|
||||
{"Right ADC", NULL, "GPIO1 dmic modclk"},
|
||||
|
||||
/*
|
||||
* Logical path between digital mic enable and GPIO1 modulator clock
|
||||
* output function
|
||||
*/
|
||||
{"GPIO1 dmic modclk", NULL, "DMic Rate 128"},
|
||||
{"GPIO1 dmic modclk", NULL, "DMic Rate 64"},
|
||||
{"GPIO1 dmic modclk", NULL, "DMic Rate 32"},
|
||||
|
||||
/* Left DAC Output */
|
||||
{"Left DAC Mux", "DAC_L1", "Left DAC"},
|
||||
|
@ -761,10 +824,8 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
{"Right DAC Mux", "DAC_R3", "Right DAC"},
|
||||
|
||||
/* Left Line Output */
|
||||
{"Left Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Left Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
|
||||
{"Left Line Mixer", "DACL1 Switch", "Left DAC Mux"},
|
||||
{"Left Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
{"Left Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
|
||||
{"Left Line Mixer", "DACR1 Switch", "Right DAC Mux"},
|
||||
|
||||
|
@ -773,10 +834,8 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
{"LLOUT", NULL, "Left Line Out"},
|
||||
|
||||
/* Right Line Output */
|
||||
{"Right Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Right Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
|
||||
{"Right Line Mixer", "DACL1 Switch", "Left DAC Mux"},
|
||||
{"Right Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
{"Right Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
|
||||
{"Right Line Mixer", "DACR1 Switch", "Right DAC Mux"},
|
||||
|
||||
|
@ -785,10 +844,8 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
{"RLOUT", NULL, "Right Line Out"},
|
||||
|
||||
/* Left HP Output */
|
||||
{"Left HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Left HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
|
||||
{"Left HP Mixer", "DACL1 Switch", "Left DAC Mux"},
|
||||
{"Left HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
{"Left HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
|
||||
{"Left HP Mixer", "DACR1 Switch", "Right DAC Mux"},
|
||||
|
||||
|
@ -797,10 +854,8 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
{"HPLOUT", NULL, "Left HP Out"},
|
||||
|
||||
/* Right HP Output */
|
||||
{"Right HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Right HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
|
||||
{"Right HP Mixer", "DACL1 Switch", "Left DAC Mux"},
|
||||
{"Right HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
{"Right HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
|
||||
{"Right HP Mixer", "DACR1 Switch", "Right DAC Mux"},
|
||||
|
||||
|
@ -809,10 +864,8 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
{"HPROUT", NULL, "Right HP Out"},
|
||||
|
||||
/* Left HPCOM Output */
|
||||
{"Left HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Left HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
|
||||
{"Left HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"},
|
||||
{"Left HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
{"Left HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
|
||||
{"Left HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"},
|
||||
|
||||
|
@ -823,10 +876,8 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
{"HPLCOM", NULL, "Left HP Com"},
|
||||
|
||||
/* Right HPCOM Output */
|
||||
{"Right HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Right HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
|
||||
{"Right HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"},
|
||||
{"Right HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
{"Right HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
|
||||
{"Right HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"},
|
||||
|
||||
|
@ -839,6 +890,72 @@ static const struct snd_soc_dapm_route intercon[] = {
|
|||
{"HPRCOM", NULL, "Right HP Com"},
|
||||
};
|
||||
|
||||
/* For other than tlv320aic3104 */
|
||||
static const struct snd_soc_dapm_route intercon_extra[] = {
|
||||
/* Left Input */
|
||||
{"Left Line2L Mux", "single-ended", "LINE2L"},
|
||||
{"Left Line2L Mux", "differential", "LINE2L"},
|
||||
|
||||
{"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"},
|
||||
{"Left PGA Mixer", "Mic3L Switch", "MIC3L"},
|
||||
{"Left PGA Mixer", "Mic3R Switch", "MIC3R"},
|
||||
|
||||
{"Left ADC", NULL, "GPIO1 dmic modclk"},
|
||||
|
||||
/* Right Input */
|
||||
{"Right Line2R Mux", "single-ended", "LINE2R"},
|
||||
{"Right Line2R Mux", "differential", "LINE2R"},
|
||||
|
||||
{"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"},
|
||||
{"Right PGA Mixer", "Mic3L Switch", "MIC3L"},
|
||||
{"Right PGA Mixer", "Mic3R Switch", "MIC3R"},
|
||||
|
||||
{"Right ADC", NULL, "GPIO1 dmic modclk"},
|
||||
|
||||
/*
|
||||
* Logical path between digital mic enable and GPIO1 modulator clock
|
||||
* output function
|
||||
*/
|
||||
{"GPIO1 dmic modclk", NULL, "DMic Rate 128"},
|
||||
{"GPIO1 dmic modclk", NULL, "DMic Rate 64"},
|
||||
{"GPIO1 dmic modclk", NULL, "DMic Rate 32"},
|
||||
|
||||
/* Left Line Output */
|
||||
{"Left Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Left Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
|
||||
/* Right Line Output */
|
||||
{"Right Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Right Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
|
||||
/* Left HP Output */
|
||||
{"Left HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Left HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
|
||||
/* Right HP Output */
|
||||
{"Right HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Right HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
|
||||
/* Left HPCOM Output */
|
||||
{"Left HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Left HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
|
||||
/* Right HPCOM Output */
|
||||
{"Right HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
{"Right HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
|
||||
};
|
||||
|
||||
/* For tlv320aic3104 */
|
||||
static const struct snd_soc_dapm_route intercon_extra_3104[] = {
|
||||
/* Left Input */
|
||||
{"Left PGA Mixer", "Mic2L Switch", "MIC2L"},
|
||||
{"Left PGA Mixer", "Mic2R Switch", "MIC2R"},
|
||||
|
||||
/* Right Input */
|
||||
{"Right PGA Mixer", "Mic2L Switch", "MIC2L"},
|
||||
{"Right PGA Mixer", "Mic2R Switch", "MIC2R"},
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route intercon_mono[] = {
|
||||
/* Mono Output */
|
||||
{"Mono Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
|
||||
|
@ -867,17 +984,31 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
|
|||
switch (aic3x->model) {
|
||||
case AIC3X_MODEL_3X:
|
||||
case AIC3X_MODEL_33:
|
||||
snd_soc_dapm_new_controls(dapm, aic3x_extra_dapm_widgets,
|
||||
ARRAY_SIZE(aic3x_extra_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(dapm, intercon_extra,
|
||||
ARRAY_SIZE(intercon_extra));
|
||||
snd_soc_dapm_new_controls(dapm, aic3x_dapm_mono_widgets,
|
||||
ARRAY_SIZE(aic3x_dapm_mono_widgets));
|
||||
snd_soc_dapm_add_routes(dapm, intercon_mono,
|
||||
ARRAY_SIZE(intercon_mono));
|
||||
break;
|
||||
case AIC3X_MODEL_3007:
|
||||
snd_soc_dapm_new_controls(dapm, aic3x_extra_dapm_widgets,
|
||||
ARRAY_SIZE(aic3x_extra_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(dapm, intercon_extra,
|
||||
ARRAY_SIZE(intercon_extra));
|
||||
snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets,
|
||||
ARRAY_SIZE(aic3007_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(dapm, intercon_3007,
|
||||
ARRAY_SIZE(intercon_3007));
|
||||
break;
|
||||
case AIC3X_MODEL_3104:
|
||||
snd_soc_dapm_new_controls(dapm, aic3104_extra_dapm_widgets,
|
||||
ARRAY_SIZE(aic3104_extra_dapm_widgets));
|
||||
snd_soc_dapm_add_routes(dapm, intercon_extra_3104,
|
||||
ARRAY_SIZE(intercon_extra_3104));
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1046,7 +1177,7 @@ static int aic3x_prepare(struct snd_pcm_substream *substream,
|
|||
delay += aic3x->tdm_delay;
|
||||
|
||||
/* Configure data delay */
|
||||
snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, aic3x->tdm_delay);
|
||||
snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1438,23 +1569,33 @@ static int aic3x_probe(struct snd_soc_codec *codec)
|
|||
aic3x_init(codec);
|
||||
|
||||
if (aic3x->setup) {
|
||||
/* setup GPIO functions */
|
||||
snd_soc_write(codec, AIC3X_GPIO1_REG,
|
||||
(aic3x->setup->gpio_func[0] & 0xf) << 4);
|
||||
snd_soc_write(codec, AIC3X_GPIO2_REG,
|
||||
(aic3x->setup->gpio_func[1] & 0xf) << 4);
|
||||
if (aic3x->model != AIC3X_MODEL_3104) {
|
||||
/* setup GPIO functions */
|
||||
snd_soc_write(codec, AIC3X_GPIO1_REG,
|
||||
(aic3x->setup->gpio_func[0] & 0xf) << 4);
|
||||
snd_soc_write(codec, AIC3X_GPIO2_REG,
|
||||
(aic3x->setup->gpio_func[1] & 0xf) << 4);
|
||||
} else {
|
||||
dev_warn(codec->dev, "GPIO functionality is not supported on tlv320aic3104\n");
|
||||
}
|
||||
}
|
||||
|
||||
switch (aic3x->model) {
|
||||
case AIC3X_MODEL_3X:
|
||||
case AIC3X_MODEL_33:
|
||||
snd_soc_add_codec_controls(codec, aic3x_extra_snd_controls,
|
||||
ARRAY_SIZE(aic3x_extra_snd_controls));
|
||||
snd_soc_add_codec_controls(codec, aic3x_mono_controls,
|
||||
ARRAY_SIZE(aic3x_mono_controls));
|
||||
break;
|
||||
case AIC3X_MODEL_3007:
|
||||
snd_soc_add_codec_controls(codec, aic3x_extra_snd_controls,
|
||||
ARRAY_SIZE(aic3x_extra_snd_controls));
|
||||
snd_soc_add_codec_controls(codec,
|
||||
&aic3x_classd_amp_gain_ctrl, 1);
|
||||
break;
|
||||
case AIC3X_MODEL_3104:
|
||||
break;
|
||||
}
|
||||
|
||||
/* set mic bias voltage */
|
||||
|
@ -1522,6 +1663,7 @@ static const struct i2c_device_id aic3x_i2c_id[] = {
|
|||
{ "tlv320aic33", AIC3X_MODEL_33 },
|
||||
{ "tlv320aic3007", AIC3X_MODEL_3007 },
|
||||
{ "tlv320aic3106", AIC3X_MODEL_3X },
|
||||
{ "tlv320aic3104", AIC3X_MODEL_3104 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
|
||||
|
@ -1673,6 +1815,7 @@ static const struct of_device_id tlv320aic3x_of_match[] = {
|
|||
{ .compatible = "ti,tlv320aic33" },
|
||||
{ .compatible = "ti,tlv320aic3007" },
|
||||
{ .compatible = "ti,tlv320aic3106" },
|
||||
{ .compatible = "ti,tlv320aic3104" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match);
|
||||
|
|
|
@ -423,17 +423,18 @@ exit:
|
|||
static int dac33_playback_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
if (likely(dac33->substream)) {
|
||||
dac33_calculate_times(dac33->substream, w->codec);
|
||||
dac33_prepare_chip(dac33->substream, w->codec);
|
||||
dac33_calculate_times(dac33->substream, codec);
|
||||
dac33_prepare_chip(dac33->substream, codec);
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
dac33_disable_digital(w->codec);
|
||||
dac33_disable_digital(codec);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include <sound/jack.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "ts3a227e.h"
|
||||
|
||||
struct ts3a227e {
|
||||
struct regmap *regmap;
|
||||
struct snd_soc_jack *jack;
|
||||
|
@ -79,6 +81,10 @@ static const int ts3a227e_buttons[] = {
|
|||
/* TS3A227E_REG_SETTING_2 0x05 */
|
||||
#define KP_ENABLE 0x04
|
||||
|
||||
/* TS3A227E_REG_SETTING_3 0x06 */
|
||||
#define MICBIAS_SETTING_SFT (3)
|
||||
#define MICBIAS_SETTING_MASK (0x7 << MICBIAS_SETTING_SFT)
|
||||
|
||||
/* TS3A227E_REG_ACCESSORY_STATUS 0x0b */
|
||||
#define TYPE_3_POLE 0x01
|
||||
#define TYPE_4_POLE_OMTP 0x02
|
||||
|
@ -221,9 +227,9 @@ int ts3a227e_enable_jack_detect(struct snd_soc_component *component,
|
|||
struct ts3a227e *ts3a227e = snd_soc_component_get_drvdata(component);
|
||||
|
||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
|
||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
|
||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
|
||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
|
||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
|
||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
|
||||
snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
|
||||
|
||||
ts3a227e->jack = jack;
|
||||
ts3a227e_jack_report(ts3a227e);
|
||||
|
@ -248,6 +254,21 @@ static const struct regmap_config ts3a227e_regmap_config = {
|
|||
.num_reg_defaults = ARRAY_SIZE(ts3a227e_reg_defaults),
|
||||
};
|
||||
|
||||
static int ts3a227e_parse_dt(struct ts3a227e *ts3a227e, struct device_node *np)
|
||||
{
|
||||
u32 micbias;
|
||||
int err;
|
||||
|
||||
err = of_property_read_u32(np, "ti,micbias", &micbias);
|
||||
if (!err) {
|
||||
regmap_update_bits(ts3a227e->regmap, TS3A227E_REG_SETTING_3,
|
||||
MICBIAS_SETTING_MASK,
|
||||
(micbias & 0x07) << MICBIAS_SETTING_SFT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ts3a227e_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
@ -266,6 +287,14 @@ static int ts3a227e_i2c_probe(struct i2c_client *i2c,
|
|||
if (IS_ERR(ts3a227e->regmap))
|
||||
return PTR_ERR(ts3a227e->regmap);
|
||||
|
||||
if (dev->of_node) {
|
||||
ret = ts3a227e_parse_dt(ts3a227e, dev->of_node);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to parse device tree: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = devm_request_threaded_irq(dev, i2c->irq, NULL, ts3a227e_interrupt,
|
||||
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||
"TS3A227E", ts3a227e);
|
||||
|
|
|
@ -567,12 +567,13 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control =
|
|||
static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
|
||||
struct snd_kcontrol *kcontrol, int event) \
|
||||
{ \
|
||||
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); \
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); \
|
||||
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); \
|
||||
\
|
||||
switch (event) { \
|
||||
case SND_SOC_DAPM_POST_PMU: \
|
||||
twl4030->pin_name##_enabled = 1; \
|
||||
twl4030_write(w->codec, reg, twl4030_read(w->codec, reg)); \
|
||||
twl4030_write(codec, reg, twl4030_read(codec, reg)); \
|
||||
break; \
|
||||
case SND_SOC_DAPM_POST_PMD: \
|
||||
twl4030->pin_name##_enabled = 0; \
|
||||
|
@ -621,12 +622,14 @@ static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
|
|||
static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 1);
|
||||
handsfree_ramp(codec, TWL4030_REG_HFL_CTL, 1);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 0);
|
||||
handsfree_ramp(codec, TWL4030_REG_HFL_CTL, 0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -635,12 +638,14 @@ static int handsfreelpga_event(struct snd_soc_dapm_widget *w,
|
|||
static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 1);
|
||||
handsfree_ramp(codec, TWL4030_REG_HFR_CTL, 1);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 0);
|
||||
handsfree_ramp(codec, TWL4030_REG_HFR_CTL, 0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -649,19 +654,23 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
|
|||
static int vibramux_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
twl4030_write(codec, TWL4030_REG_VIBRA_SET, 0xff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apll_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
twl4030_apll_enable(w->codec, 1);
|
||||
twl4030_apll_enable(codec, 1);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
twl4030_apll_enable(w->codec, 0);
|
||||
twl4030_apll_enable(codec, 0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -670,23 +679,24 @@ static int apll_event(struct snd_soc_dapm_widget *w,
|
|||
static int aif_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
u8 audio_if;
|
||||
|
||||
audio_if = twl4030_read(w->codec, TWL4030_REG_AUDIO_IF);
|
||||
audio_if = twl4030_read(codec, TWL4030_REG_AUDIO_IF);
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
/* Enable AIF */
|
||||
/* enable the PLL before we use it to clock the DAI */
|
||||
twl4030_apll_enable(w->codec, 1);
|
||||
twl4030_apll_enable(codec, 1);
|
||||
|
||||
twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
|
||||
twl4030_write(codec, TWL4030_REG_AUDIO_IF,
|
||||
audio_if | TWL4030_AIF_EN);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* disable the DAI before we stop it's source PLL */
|
||||
twl4030_write(w->codec, TWL4030_REG_AUDIO_IF,
|
||||
twl4030_write(codec, TWL4030_REG_AUDIO_IF,
|
||||
audio_if & ~TWL4030_AIF_EN);
|
||||
twl4030_apll_enable(w->codec, 0);
|
||||
twl4030_apll_enable(codec, 0);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -758,20 +768,21 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
|
|||
static int headsetlpga_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/* Do the ramp-up only once */
|
||||
if (!twl4030->hsr_enabled)
|
||||
headset_ramp(w->codec, 1);
|
||||
headset_ramp(codec, 1);
|
||||
|
||||
twl4030->hsl_enabled = 1;
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* Do the ramp-down only if both headsetL/R is disabled */
|
||||
if (!twl4030->hsr_enabled)
|
||||
headset_ramp(w->codec, 0);
|
||||
headset_ramp(codec, 0);
|
||||
|
||||
twl4030->hsl_enabled = 0;
|
||||
break;
|
||||
|
@ -782,20 +793,21 @@ static int headsetlpga_event(struct snd_soc_dapm_widget *w,
|
|||
static int headsetrpga_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/* Do the ramp-up only once */
|
||||
if (!twl4030->hsl_enabled)
|
||||
headset_ramp(w->codec, 1);
|
||||
headset_ramp(codec, 1);
|
||||
|
||||
twl4030->hsr_enabled = 1;
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* Do the ramp-down only if both headsetL/R is disabled */
|
||||
if (!twl4030->hsl_enabled)
|
||||
headset_ramp(w->codec, 0);
|
||||
headset_ramp(codec, 0);
|
||||
|
||||
twl4030->hsr_enabled = 0;
|
||||
break;
|
||||
|
@ -806,7 +818,8 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
|
|||
static int digimic_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
|
||||
struct twl4030_codec_data *pdata = twl4030->pdata;
|
||||
|
||||
if (pdata && pdata->digimic_delay)
|
||||
|
|
|
@ -234,7 +234,7 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf)
|
|||
static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
u8 hslctl, hsrctl;
|
||||
|
||||
/*
|
||||
|
@ -261,7 +261,7 @@ static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w,
|
|||
static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
|
||||
int ret = 0;
|
||||
|
||||
|
|
|
@ -683,7 +683,7 @@ static const struct snd_kcontrol_new wm2000_controls[] = {
|
|||
static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev);
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -775,7 +775,8 @@ static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (w->reg) {
|
||||
case WM5100_CHANNEL_ENABLES_1:
|
||||
|
@ -839,7 +840,7 @@ static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <linux/mfd/arizona/core.h>
|
||||
#include <linux/mfd/arizona/registers.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "arizona.h"
|
||||
#include "wm5102.h"
|
||||
|
@ -580,7 +581,7 @@ static const struct reg_default wm5102_sysclk_revb_patch[] = {
|
|||
static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
|
||||
struct regmap *regmap = arizona->regmap;
|
||||
const struct reg_default *patch = NULL;
|
||||
|
@ -617,11 +618,10 @@ static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol,
|
|||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
|
||||
uint16_t data;
|
||||
|
||||
mutex_lock(&arizona->dac_comp_lock);
|
||||
data = cpu_to_be16(arizona->dac_comp_coeff);
|
||||
memcpy(ucontrol->value.bytes.data, &data, sizeof(data));
|
||||
put_unaligned_be16(arizona->dac_comp_coeff,
|
||||
ucontrol->value.bytes.data);
|
||||
mutex_unlock(&arizona->dac_comp_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -1272,19 +1272,24 @@ SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
|
|||
|
||||
SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
|
||||
ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
|
||||
ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
|
|
|
@ -134,7 +134,7 @@ static const struct reg_default wm5110_sysclk_revd_patch[] = {
|
|||
static int wm5110_sysclk_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
|
||||
struct regmap *regmap = arizona->regmap;
|
||||
const struct reg_default *patch = NULL;
|
||||
|
@ -905,22 +905,28 @@ SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
|
|||
|
||||
SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
|
||||
ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
|
||||
ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
|
|
|
@ -259,7 +259,7 @@ static void wm8350_pga_work(struct work_struct *work)
|
|||
static int pga_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8350_output *out;
|
||||
|
||||
|
|
|
@ -324,6 +324,7 @@ SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME,
|
|||
static int outmixer_event (struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol * kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct soc_mixer_control *mc =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
u32 reg_shift = mc->shift;
|
||||
|
@ -332,7 +333,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
|
|||
|
||||
switch (reg_shift) {
|
||||
case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) :
|
||||
reg = snd_soc_read(w->codec, WM8400_OUTPUT_MIXER1);
|
||||
reg = snd_soc_read(codec, WM8400_OUTPUT_MIXER1);
|
||||
if (reg & WM8400_LDLO) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Output Mixer 1 LDLO Set\n");
|
||||
|
@ -340,7 +341,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
|
|||
}
|
||||
break;
|
||||
case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8):
|
||||
reg = snd_soc_read(w->codec, WM8400_OUTPUT_MIXER2);
|
||||
reg = snd_soc_read(codec, WM8400_OUTPUT_MIXER2);
|
||||
if (reg & WM8400_RDRO) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Output Mixer 2 RDRO Set\n");
|
||||
|
@ -348,7 +349,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
|
|||
}
|
||||
break;
|
||||
case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8):
|
||||
reg = snd_soc_read(w->codec, WM8400_SPEAKER_MIXER);
|
||||
reg = snd_soc_read(codec, WM8400_SPEAKER_MIXER);
|
||||
if (reg & WM8400_LDSPK) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Speaker Mixer LDSPK Set\n");
|
||||
|
@ -356,7 +357,7 @@ static int outmixer_event (struct snd_soc_dapm_widget *w,
|
|||
}
|
||||
break;
|
||||
case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8):
|
||||
reg = snd_soc_read(w->codec, WM8400_SPEAKER_MIXER);
|
||||
reg = snd_soc_read(codec, WM8400_SPEAKER_MIXER);
|
||||
if (reg & WM8400_RDSPK) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Speaker Mixer RDSPK Set\n");
|
||||
|
|
|
@ -217,7 +217,8 @@ SND_SOC_DAPM_INPUT("LLINEIN"),
|
|||
static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(source->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
return wm8731->sysclk_type == WM8731_SYSCLK_XTAL;
|
||||
}
|
||||
|
@ -717,6 +718,8 @@ static int wm8731_i2c_probe(struct i2c_client *i2c,
|
|||
if (wm8731 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&wm8731->lock);
|
||||
|
||||
wm8731->regmap = devm_regmap_init_i2c(i2c, &wm8731_regmap);
|
||||
if (IS_ERR(wm8731->regmap)) {
|
||||
ret = PTR_ERR(wm8731->regmap);
|
||||
|
|
|
@ -308,9 +308,7 @@ static const struct snd_soc_dapm_route wm8770_intercon[] = {
|
|||
static int vout12supply_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec;
|
||||
|
||||
codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
|
@ -327,9 +325,7 @@ static int vout12supply_event(struct snd_soc_dapm_widget *w,
|
|||
static int vout34supply_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec;
|
||||
|
||||
codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
|
|
|
@ -648,7 +648,7 @@ static struct snd_soc_dai_driver wm8804_dai = {
|
|||
.symmetric_rates = 1
|
||||
};
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
|
||||
static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
|
||||
.probe = wm8804_probe,
|
||||
.remove = wm8804_remove,
|
||||
.set_bias_level = wm8804_set_bias_level,
|
||||
|
@ -664,7 +664,7 @@ static const struct of_device_id wm8804_of_match[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(of, wm8804_of_match);
|
||||
|
||||
static struct regmap_config wm8804_regmap_config = {
|
||||
static const struct regmap_config wm8804_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ static void wm8900_reset(struct snd_soc_codec *codec)
|
|||
static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1);
|
||||
|
||||
switch (event) {
|
||||
|
|
|
@ -260,7 +260,7 @@ static int wm8903_cp_event(struct snd_soc_dapm_widget *w,
|
|||
static int wm8903_dcs_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
|
|
@ -673,7 +673,7 @@ static int cp_event(struct snd_soc_dapm_widget *w,
|
|||
static int sysclk_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -711,7 +711,7 @@ static int sysclk_event(struct snd_soc_dapm_widget *w,
|
|||
static int out_pga_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
|
||||
int reg, val;
|
||||
int dcs_mask;
|
||||
|
@ -2105,6 +2105,24 @@ static const struct regmap_config wm8904_regmap = {
|
|||
.num_reg_defaults = ARRAY_SIZE(wm8904_reg_defaults),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static enum wm8904_type wm8904_data = WM8904;
|
||||
static enum wm8904_type wm8912_data = WM8912;
|
||||
|
||||
static const struct of_device_id wm8904_of_match[] = {
|
||||
{
|
||||
.compatible = "wlf,wm8904",
|
||||
.data = &wm8904_data,
|
||||
}, {
|
||||
.compatible = "wlf,wm8912",
|
||||
.data = &wm8912_data,
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, wm8904_of_match);
|
||||
#endif
|
||||
|
||||
static int wm8904_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
|
@ -2132,7 +2150,17 @@ static int wm8904_i2c_probe(struct i2c_client *i2c,
|
|||
return ret;
|
||||
}
|
||||
|
||||
wm8904->devtype = id->driver_data;
|
||||
if (i2c->dev.of_node) {
|
||||
const struct of_device_id *match;
|
||||
|
||||
match = of_match_node(wm8904_of_match, i2c->dev.of_node);
|
||||
if (match == NULL)
|
||||
return -EINVAL;
|
||||
wm8904->devtype = *((enum wm8904_type *)match->data);
|
||||
} else {
|
||||
wm8904->devtype = id->driver_data;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(i2c, wm8904);
|
||||
wm8904->pdata = i2c->dev.platform_data;
|
||||
|
||||
|
@ -2266,6 +2294,7 @@ static struct i2c_driver wm8904_i2c_driver = {
|
|||
.driver = {
|
||||
.name = "wm8904",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(wm8904_of_match),
|
||||
},
|
||||
.probe = wm8904_i2c_probe,
|
||||
.remove = wm8904_i2c_remove,
|
||||
|
|
|
@ -333,7 +333,7 @@ static int wm8955_configure_clocking(struct snd_soc_codec *codec)
|
|||
static int wm8955_sysclk(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
int ret = 0;
|
||||
|
||||
/* Always disable the clocks - if we're doing reconfiguration this
|
||||
|
|
|
@ -418,7 +418,7 @@ static void wm8958_dsp_apply(struct snd_soc_codec *codec, int path, int start)
|
|||
int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
int i;
|
||||
|
||||
switch (event) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/slab.h>
|
||||
#include <sound/core.h>
|
||||
|
@ -117,6 +118,7 @@ static bool wm8960_volatile(struct device *dev, unsigned int reg)
|
|||
}
|
||||
|
||||
struct wm8960_priv {
|
||||
struct clk *mclk;
|
||||
struct regmap *regmap;
|
||||
int (*set_bias_level)(struct snd_soc_codec *,
|
||||
enum snd_soc_bias_level level);
|
||||
|
@ -618,14 +620,38 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
|
|||
enum snd_soc_bias_level level)
|
||||
{
|
||||
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret;
|
||||
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
/* Set VMID to 2x50k */
|
||||
snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80);
|
||||
switch (codec->dapm.bias_level) {
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
if (!IS_ERR(wm8960->mclk)) {
|
||||
ret = clk_prepare_enable(wm8960->mclk);
|
||||
if (ret) {
|
||||
dev_err(codec->dev,
|
||||
"Failed to enable MCLK: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set VMID to 2x50k */
|
||||
snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80);
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_ON:
|
||||
if (!IS_ERR(wm8960->mclk))
|
||||
clk_disable_unprepare(wm8960->mclk);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
|
@ -674,7 +700,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
|
|||
enum snd_soc_bias_level level)
|
||||
{
|
||||
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
|
||||
int reg;
|
||||
int reg, ret;
|
||||
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
|
@ -715,9 +741,22 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
|
|||
WM8960_VREF, WM8960_VREF);
|
||||
|
||||
msleep(100);
|
||||
|
||||
if (!IS_ERR(wm8960->mclk)) {
|
||||
ret = clk_prepare_enable(wm8960->mclk);
|
||||
if (ret) {
|
||||
dev_err(codec->dev,
|
||||
"Failed to enable MCLK: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_ON:
|
||||
if (!IS_ERR(wm8960->mclk))
|
||||
clk_disable_unprepare(wm8960->mclk);
|
||||
|
||||
/* Enable anti-pop mode */
|
||||
snd_soc_update_bits(codec, WM8960_APOP1,
|
||||
WM8960_POBCTRL | WM8960_SOFT_ST |
|
||||
|
@ -1002,6 +1041,12 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
|
|||
if (wm8960 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
wm8960->mclk = devm_clk_get(&i2c->dev, "mclk");
|
||||
if (IS_ERR(wm8960->mclk)) {
|
||||
if (PTR_ERR(wm8960->mclk) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
wm8960->regmap = devm_regmap_init_i2c(i2c, &wm8960_regmap);
|
||||
if (IS_ERR(wm8960->regmap))
|
||||
return PTR_ERR(wm8960->regmap);
|
||||
|
|
|
@ -194,7 +194,7 @@ static bool wm8961_readable(struct device *dev, unsigned int reg)
|
|||
static int wm8961_hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
u16 hp_reg = snd_soc_read(codec, WM8961_ANALOGUE_HP_0);
|
||||
u16 cp_reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_1);
|
||||
u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
|
||||
|
@ -286,7 +286,7 @@ static int wm8961_hp_event(struct snd_soc_dapm_widget *w,
|
|||
static int wm8961_spk_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
|
||||
u16 spk_reg = snd_soc_read(codec, WM8961_CLASS_D_CONTROL_1);
|
||||
|
||||
|
|
|
@ -1866,7 +1866,7 @@ static int cp_event(struct snd_soc_dapm_widget *w,
|
|||
static int hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
int timeout;
|
||||
int reg;
|
||||
int expected = (WM8962_DCS_STARTUP_DONE_HP1L |
|
||||
|
@ -1960,7 +1960,7 @@ static int hp_event(struct snd_soc_dapm_widget *w,
|
|||
static int out_pga_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
int reg;
|
||||
|
||||
switch (w->shift) {
|
||||
|
@ -1993,7 +1993,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
|
|||
static int dsp2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
|
|
@ -244,7 +244,7 @@ SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V,
|
|||
static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
u16 adctl2 = snd_soc_read(codec, WM8988_ADCTL2);
|
||||
|
||||
/* Use the DAC to gate LRC if active, otherwise use ADC */
|
||||
|
@ -813,7 +813,7 @@ static int wm8988_probe(struct snd_soc_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
|
||||
static const struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
|
||||
.probe = wm8988_probe,
|
||||
.set_bias_level = wm8988_set_bias_level,
|
||||
.suspend_bias_off = true,
|
||||
|
@ -826,7 +826,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = {
|
|||
.num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes),
|
||||
};
|
||||
|
||||
static struct regmap_config wm8988_regmap = {
|
||||
static const struct regmap_config wm8988_regmap = {
|
||||
.reg_bits = 7,
|
||||
.val_bits = 9,
|
||||
|
||||
|
|
|
@ -374,13 +374,14 @@ SOC_SINGLE("RIN34 Mute Switch", WM8990_RIGHT_LINE_INPUT_3_4_VOLUME,
|
|||
static int outmixer_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
u32 reg_shift = kcontrol->private_value & 0xfff;
|
||||
int ret = 0;
|
||||
u16 reg;
|
||||
|
||||
switch (reg_shift) {
|
||||
case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) :
|
||||
reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER1);
|
||||
reg = snd_soc_read(codec, WM8990_OUTPUT_MIXER1);
|
||||
if (reg & WM8990_LDLO) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Output Mixer 1 LDLO Set\n");
|
||||
|
@ -388,7 +389,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
|
|||
}
|
||||
break;
|
||||
case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8):
|
||||
reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER2);
|
||||
reg = snd_soc_read(codec, WM8990_OUTPUT_MIXER2);
|
||||
if (reg & WM8990_RDRO) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Output Mixer 2 RDRO Set\n");
|
||||
|
@ -396,7 +397,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
|
|||
}
|
||||
break;
|
||||
case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8):
|
||||
reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER);
|
||||
reg = snd_soc_read(codec, WM8990_SPEAKER_MIXER);
|
||||
if (reg & WM8990_LDSPK) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Speaker Mixer LDSPK Set\n");
|
||||
|
@ -404,7 +405,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
|
|||
}
|
||||
break;
|
||||
case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8):
|
||||
reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER);
|
||||
reg = snd_soc_read(codec, WM8990_SPEAKER_MIXER);
|
||||
if (reg & WM8990_RDSPK) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Speaker Mixer RDSPK Set\n");
|
||||
|
|
|
@ -382,13 +382,14 @@ static const struct snd_kcontrol_new wm8991_snd_controls[] = {
|
|||
static int outmixer_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
u32 reg_shift = kcontrol->private_value & 0xfff;
|
||||
int ret = 0;
|
||||
u16 reg;
|
||||
|
||||
switch (reg_shift) {
|
||||
case WM8991_SPEAKER_MIXER | (WM8991_LDSPK_BIT << 8):
|
||||
reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER1);
|
||||
reg = snd_soc_read(codec, WM8991_OUTPUT_MIXER1);
|
||||
if (reg & WM8991_LDLO) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Output Mixer 1 LDLO Set\n");
|
||||
|
@ -397,7 +398,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
|
|||
break;
|
||||
|
||||
case WM8991_SPEAKER_MIXER | (WM8991_RDSPK_BIT << 8):
|
||||
reg = snd_soc_read(w->codec, WM8991_OUTPUT_MIXER2);
|
||||
reg = snd_soc_read(codec, WM8991_OUTPUT_MIXER2);
|
||||
if (reg & WM8991_RDRO) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Output Mixer 2 RDRO Set\n");
|
||||
|
@ -406,7 +407,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
|
|||
break;
|
||||
|
||||
case WM8991_OUTPUT_MIXER1 | (WM8991_LDLO_BIT << 8):
|
||||
reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER);
|
||||
reg = snd_soc_read(codec, WM8991_SPEAKER_MIXER);
|
||||
if (reg & WM8991_LDSPK) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Speaker Mixer LDSPK Set\n");
|
||||
|
@ -415,7 +416,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
|
|||
break;
|
||||
|
||||
case WM8991_OUTPUT_MIXER2 | (WM8991_RDRO_BIT << 8):
|
||||
reg = snd_soc_read(w->codec, WM8991_SPEAKER_MIXER);
|
||||
reg = snd_soc_read(codec, WM8991_SPEAKER_MIXER);
|
||||
if (reg & WM8991_RDSPK) {
|
||||
printk(KERN_WARNING
|
||||
"Cannot set as Speaker Mixer RDSPK Set\n");
|
||||
|
|
|
@ -810,7 +810,7 @@ SOC_SINGLE_TLV("EQ5 Volume", WM8993_EQ6, 0, 24, 0, eq_tlv),
|
|||
static int clk_sys_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
|
|
|
@ -249,7 +249,8 @@ static int configure_clock(struct snd_soc_codec *codec)
|
|||
static int check_clk_sys(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
int reg = snd_soc_read(source->codec, WM8994_CLOCKING_1);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
int reg = snd_soc_read(codec, WM8994_CLOCKING_1);
|
||||
const char *clk;
|
||||
|
||||
/* Check what we're currently using for CLK_SYS */
|
||||
|
@ -806,7 +807,7 @@ static void active_dereference(struct snd_soc_codec *codec)
|
|||
static int clk_sys_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -981,7 +982,7 @@ static void vmid_dereference(struct snd_soc_codec *codec)
|
|||
static int vmid_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
|
@ -1037,7 +1038,7 @@ static bool wm8994_check_class_w_digital(struct snd_soc_codec *codec)
|
|||
static int aif1clk_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm8994 *control = wm8994->wm8994;
|
||||
int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA;
|
||||
|
@ -1135,7 +1136,7 @@ static int aif1clk_ev(struct snd_soc_dapm_widget *w,
|
|||
static int aif2clk_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
int i;
|
||||
int dac;
|
||||
int adc;
|
||||
|
@ -1220,7 +1221,7 @@ static int aif2clk_ev(struct snd_soc_dapm_widget *w,
|
|||
static int aif1clk_late_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -1238,7 +1239,7 @@ static int aif1clk_late_ev(struct snd_soc_dapm_widget *w,
|
|||
static int aif2clk_late_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -1256,7 +1257,7 @@ static int aif2clk_late_ev(struct snd_soc_dapm_widget *w,
|
|||
static int late_enable_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -1289,7 +1290,7 @@ static int late_enable_ev(struct snd_soc_dapm_widget *w,
|
|||
static int late_disable_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -1331,7 +1332,7 @@ static int micbias_ev(struct snd_soc_dapm_widget *w,
|
|||
static int dac_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
unsigned int mask = 1 << w->shift;
|
||||
|
||||
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5,
|
||||
|
@ -1372,7 +1373,7 @@ SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0),
|
|||
static int post_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
dev_dbg(codec->dev, "SRC status: %x\n",
|
||||
snd_soc_read(codec,
|
||||
WM8994_RATE_STATUS));
|
||||
|
|
|
@ -44,7 +44,7 @@ static const char *wm8995_supply_names[WM8995_NUM_SUPPLIES] = {
|
|||
"MICVDD"
|
||||
};
|
||||
|
||||
static struct reg_default wm8995_reg_defaults[] = {
|
||||
static const struct reg_default wm8995_reg_defaults[] = {
|
||||
{ 0, 0x8995 },
|
||||
{ 5, 0x0100 },
|
||||
{ 16, 0x000b },
|
||||
|
@ -534,10 +534,11 @@ static void wm8995_update_class_w(struct snd_soc_codec *codec)
|
|||
static int check_clk_sys(struct snd_soc_dapm_widget *source,
|
||||
struct snd_soc_dapm_widget *sink)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
|
||||
unsigned int reg;
|
||||
const char *clk;
|
||||
|
||||
reg = snd_soc_read(source->codec, WM8995_CLOCKING_1);
|
||||
reg = snd_soc_read(codec, WM8995_CLOCKING_1);
|
||||
/* Check what we're currently using for CLK_SYS */
|
||||
if (reg & WM8995_SYSCLK_SRC)
|
||||
clk = "AIF2CLK";
|
||||
|
@ -560,9 +561,7 @@ static int wm8995_put_class_w(struct snd_kcontrol *kcontrol,
|
|||
static int hp_supply_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec;
|
||||
|
||||
codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
|
@ -611,10 +610,9 @@ static void dc_servo_cmd(struct snd_soc_codec *codec,
|
|||
static int hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
unsigned int reg;
|
||||
|
||||
codec = w->codec;
|
||||
reg = snd_soc_read(codec, WM8995_ANALOGUE_HP_1);
|
||||
|
||||
switch (event) {
|
||||
|
@ -761,9 +759,7 @@ static int configure_clock(struct snd_soc_codec *codec)
|
|||
static int clk_sys_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec;
|
||||
|
||||
codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
|
@ -2190,7 +2186,7 @@ static struct snd_soc_dai_driver wm8995_dai[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
|
||||
static const struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
|
||||
.probe = wm8995_probe,
|
||||
.remove = wm8995_remove,
|
||||
.set_bias_level = wm8995_set_bias_level,
|
||||
|
@ -2204,7 +2200,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
|
|||
.num_dapm_routes = ARRAY_SIZE(wm8995_intercon),
|
||||
};
|
||||
|
||||
static struct regmap_config wm8995_regmap = {
|
||||
static const struct regmap_config wm8995_regmap = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 16,
|
||||
|
||||
|
|
|
@ -599,7 +599,7 @@ static void wm8996_bg_disable(struct snd_soc_codec *codec)
|
|||
static int bg_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
int ret = 0;
|
||||
|
||||
switch (event) {
|
||||
|
@ -634,7 +634,8 @@ static int cp_event(struct snd_soc_dapm_widget *w,
|
|||
static int rmv_short_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
/* Record which outputs we enabled */
|
||||
switch (event) {
|
||||
|
@ -758,7 +759,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm,
|
|||
static int dcs_start(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(w->codec);
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
|
|
|
@ -84,7 +84,7 @@ static const struct reg_default wm8997_sysclk_reva_patch[] = {
|
|||
static int wm8997_sysclk_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
|
||||
struct regmap *regmap = arizona->regmap;
|
||||
const struct reg_default *patch = NULL;
|
||||
|
@ -610,13 +610,16 @@ SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
|
|||
|
||||
SND_SOC_DAPM_PGA_E("OUT1L", SND_SOC_NOPM,
|
||||
ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT1R", SND_SOC_NOPM,
|
||||
ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_hp_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
|
||||
SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
|
||||
ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
|
||||
|
|
|
@ -734,7 +734,7 @@ static int configure_clock(struct snd_soc_codec *codec)
|
|||
static int clk_sys_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
/* This should be done on init() for bypass paths */
|
||||
|
|
|
@ -254,7 +254,7 @@ SOC_SINGLE_TLV("MIXOUTR IN2B Volume", WM9090_OUTPUT_MIXER4, 0, 3, 1,
|
|||
static int hp_ev(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
unsigned int reg = snd_soc_read(codec, WM9090_ANALOGUE_HP_0);
|
||||
|
||||
switch (event) {
|
||||
|
|
|
@ -344,23 +344,27 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec)
|
|||
struct snd_ac97 *ac97;
|
||||
int ret = 0;
|
||||
|
||||
ac97 = snd_soc_new_ac97_codec(codec);
|
||||
ac97 = snd_soc_alloc_ac97_codec(codec);
|
||||
if (IS_ERR(ac97)) {
|
||||
ret = PTR_ERR(ac97);
|
||||
dev_err(codec->dev, "Failed to register AC97 codec\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
snd_soc_codec_set_drvdata(codec, ac97);
|
||||
|
||||
ret = wm9705_reset(codec);
|
||||
if (ret)
|
||||
goto reset_err;
|
||||
goto err_put_device;
|
||||
|
||||
ret = device_add(&ac97->dev);
|
||||
if (ret)
|
||||
goto err_put_device;
|
||||
|
||||
snd_soc_codec_set_drvdata(codec, ac97);
|
||||
|
||||
return 0;
|
||||
|
||||
reset_err:
|
||||
snd_soc_free_ac97_codec(ac97);
|
||||
err_put_device:
|
||||
put_device(&ac97->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -666,7 +666,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
|
|||
struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret = 0;
|
||||
|
||||
wm9712->ac97 = snd_soc_new_ac97_codec(codec);
|
||||
wm9712->ac97 = snd_soc_alloc_ac97_codec(codec);
|
||||
if (IS_ERR(wm9712->ac97)) {
|
||||
ret = PTR_ERR(wm9712->ac97);
|
||||
dev_err(codec->dev, "Failed to register AC97 codec: %d\n", ret);
|
||||
|
@ -675,15 +675,19 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec)
|
|||
|
||||
ret = wm9712_reset(codec, 0);
|
||||
if (ret < 0)
|
||||
goto reset_err;
|
||||
goto err_put_device;
|
||||
|
||||
ret = device_add(&wm9712->ac97->dev);
|
||||
if (ret)
|
||||
goto err_put_device;
|
||||
|
||||
/* set alc mux to none */
|
||||
ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000);
|
||||
|
||||
return 0;
|
||||
|
||||
reset_err:
|
||||
snd_soc_free_ac97_codec(wm9712->ac97);
|
||||
err_put_device:
|
||||
put_device(&wm9712->ac97->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
|
|||
static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
u16 status, rate;
|
||||
|
||||
if (WARN_ON(event != SND_SOC_DAPM_PRE_PMD))
|
||||
|
@ -1225,7 +1225,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
|
|||
struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
|
||||
int ret = 0, reg;
|
||||
|
||||
wm9713->ac97 = snd_soc_new_ac97_codec(codec);
|
||||
wm9713->ac97 = snd_soc_alloc_ac97_codec(codec);
|
||||
if (IS_ERR(wm9713->ac97))
|
||||
return PTR_ERR(wm9713->ac97);
|
||||
|
||||
|
@ -1234,7 +1234,11 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
|
|||
wm9713_reset(codec, 0);
|
||||
ret = wm9713_reset(codec, 1);
|
||||
if (ret < 0)
|
||||
goto reset_err;
|
||||
goto err_put_device;
|
||||
|
||||
ret = device_add(&wm9713->ac97->dev);
|
||||
if (ret)
|
||||
goto err_put_device;
|
||||
|
||||
/* unmute the adc - move to kcontrol */
|
||||
reg = ac97_read(codec, AC97_CD) & 0x7fff;
|
||||
|
@ -1242,8 +1246,8 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec)
|
|||
|
||||
return 0;
|
||||
|
||||
reset_err:
|
||||
snd_soc_free_ac97_codec(wm9713->ac97);
|
||||
err_put_device:
|
||||
put_device(&wm9713->ac97->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1373,7 +1373,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
|
|||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm_adsp *dsp = &dsps[w->shift];
|
||||
struct wm_adsp_alg_region *alg_region;
|
||||
|
@ -1605,7 +1605,7 @@ err:
|
|||
int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm_adsp *dsp = &dsps[w->shift];
|
||||
|
||||
|
@ -1626,7 +1626,7 @@ EXPORT_SYMBOL_GPL(wm_adsp2_early_event);
|
|||
int wm_adsp2_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
|
||||
struct wm_adsp *dsp = &dsps[w->shift];
|
||||
struct wm_adsp_alg_region *alg_region;
|
||||
|
|
|
@ -500,7 +500,7 @@ SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1,
|
|||
static int hp_supply_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (event) {
|
||||
|
@ -542,7 +542,7 @@ static int hp_supply_event(struct snd_soc_dapm_widget *w,
|
|||
static int hp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
unsigned int reg = snd_soc_read(codec, WM8993_ANALOGUE_HP_0);
|
||||
|
||||
switch (event) {
|
||||
|
@ -594,7 +594,7 @@ static int hp_event(struct snd_soc_dapm_widget *w,
|
|||
static int earpiece_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *control, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
u16 reg = snd_soc_read(codec, WM8993_ANTIPOP1) & ~WM8993_HPOUT2_IN_ENA;
|
||||
|
||||
switch (event) {
|
||||
|
@ -619,7 +619,7 @@ static int earpiece_event(struct snd_soc_dapm_widget *w,
|
|||
static int lineout_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *control, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
|
||||
bool *flag;
|
||||
|
||||
|
@ -649,7 +649,7 @@ static int lineout_event(struct snd_soc_dapm_widget *w,
|
|||
static int micbias_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
switch (w->shift) {
|
||||
|
|
|
@ -58,13 +58,12 @@ choice
|
|||
depends on MACH_DAVINCI_DM365_EVM
|
||||
|
||||
config SND_DM365_AIC3X_CODEC
|
||||
bool "Audio Codec - AIC3101"
|
||||
tristate "Audio Codec - AIC3101"
|
||||
help
|
||||
Say Y if you want to add support for AIC3101 audio codec
|
||||
|
||||
config SND_DM365_VOICE_CODEC
|
||||
tristate "Voice Codec - CQ93VC"
|
||||
depends on SND_DAVINCI_SOC
|
||||
select MFD_DAVINCI_VOICECODEC
|
||||
select SND_DAVINCI_SOC_VCIF
|
||||
select SND_SOC_CQ0093VC
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/edma.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/clk.h>
|
||||
|
@ -25,11 +24,6 @@
|
|||
#include <asm/dma.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <linux/edma.h>
|
||||
|
||||
#include "davinci-pcm.h"
|
||||
#include "davinci-i2s.h"
|
||||
|
||||
struct snd_soc_card_drvdata_davinci {
|
||||
struct clk *mclk;
|
||||
unsigned sysclk;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue