提交 89fc594b 编写于 作者: M Mark Brown

Merge tag 'asoc-v4.2' into asoc-next

ASoC: Updates for v4.2

The big thing this release has been Liam's addition of topology support
to the core.  We've also seen quite a bit of driver work and the
continuation of Lars' refactoring for component support.

 - Support for loading ASoC topology maps from firmware, intended to be
   used to allow self-describing DSP firmware images to be built which
   can map controls added by the DSP to userspace without the kernel
   needing to know about individual DSP firmwares.
 - Lots of refactoring to avoid direct access to snd_soc_codec where
   it's not needed supporting future refactoring.
 - Big refactoring and cleanup serieses for the Wolfson ADSP and TI
   TAS2552 drivers.
 - Support for TI TAS571x power amplifiers.
 - Support for Qualcomm APQ8016 and ZTE ZX296702 SoCs.
 - Support for x86 systems with RT5650 and Qualcomm Storm.

# gpg: Signature made Mon 08 Jun 2015 18:48:37 BST using RSA key ID 5D5487D0
# gpg: Oops: keyid_from_fingerprint: no pubkey
# gpg: Good signature from "Mark Brown <broonie@sirena.org.uk>"
# gpg:                 aka "Mark Brown <broonie@debian.org>"
# gpg:                 aka "Mark Brown <broonie@kernel.org>"
# gpg:                 aka "Mark Brown <broonie@tardis.ed.ac.uk>"
# gpg:                 aka "Mark Brown <broonie@linaro.org>"
# gpg:                 aka "Mark Brown <Mark.Brown@linaro.org>"
...@@ -20,6 +20,8 @@ Optional properties: ...@@ -20,6 +20,8 @@ Optional properties:
pin configurations as described in the datasheet, pin configurations as described in the datasheet,
table 53. Note that the value of this property has table 53. Note that the value of this property has
to be prefixed with '/bits/ 8'. to be prefixed with '/bits/ 8'.
- avdd-supply: Power supply for AVDD, providing 3.3V
- dvdd-supply: Power supply for DVDD, providing 3.3V
Examples: Examples:
...@@ -28,6 +30,8 @@ Examples: ...@@ -28,6 +30,8 @@ Examples:
compatible = "adi,adau1701"; compatible = "adi,adau1701";
reg = <0x34>; reg = <0x34>;
reset-gpio = <&gpio 23 0>; reset-gpio = <&gpio 23 0>;
avdd-supply = <&vdd_3v3_reg>;
dvdd-supply = <&vdd_3v3_reg>;
adi,pll-mode-gpios = <&gpio 24 0 &gpio 25 0>; adi,pll-mode-gpios = <&gpio 24 0 &gpio 25 0>;
adi,pin-config = /bits/ 8 <0x4 0x7 0x5 0x5 0x4 0x4 adi,pin-config = /bits/ 8 <0x4 0x7 0x5 0x5 0x4 0x4
0x4 0x4 0x4 0x4 0x4 0x4>; 0x4 0x4 0x4 0x4 0x4 0x4>;
......
Bluetooth-SCO audio CODEC
This device support generic Bluetooth SCO link.
Required properties:
- compatible : "delta,dfbmcs320"
Example:
codec: bt_sco {
compatible = "delta,dfbmcs320";
};
GTM601 UMTS modem audio interface CODEC
This device has no configuration interface. Sample rate is fixed - 8kHz.
Required properties:
- compatible : "option,gtm601"
Example:
codec: gtm601_codec {
compatible = "option,gtm601";
};
...@@ -18,6 +18,12 @@ Optional properties: ...@@ -18,6 +18,12 @@ Optional properties:
- maxim,dmic-freq: Frequency at which to clock DMIC - maxim,dmic-freq: Frequency at which to clock DMIC
- maxim,micbias: Micbias voltage applies to the analog mic, valid voltages value are:
0 - 2.2v
1 - 2.55v
2 - 2.4v
3 - 2.8v
Pins on the device (for linking into audio routes): Pins on the device (for linking into audio routes):
* MIC1 * MIC1
......
...@@ -4,12 +4,21 @@ This node models the Qualcomm Technologies Low-Power Audio SubSystem (LPASS). ...@@ -4,12 +4,21 @@ This node models the Qualcomm Technologies Low-Power Audio SubSystem (LPASS).
Required properties: Required properties:
- compatible : "qcom,lpass-cpu" - compatible : "qcom,lpass-cpu" or "qcom,apq8016-lpass-cpu"
- clocks : Must contain an entry for each entry in clock-names. - clocks : Must contain an entry for each entry in clock-names.
- clock-names : A list which must include the following entries: - clock-names : A list which must include the following entries:
* "ahbix-clk" * "ahbix-clk"
* "mi2s-osr-clk" * "mi2s-osr-clk"
* "mi2s-bit-clk" * "mi2s-bit-clk"
: required clocks for "qcom,lpass-cpu-apq8016"
* "ahbix-clk"
* "mi2s-bit-clk0"
* "mi2s-bit-clk1"
* "mi2s-bit-clk2"
* "mi2s-bit-clk3"
* "pcnoc-mport-clk"
* "pcnoc-sway-clk"
- interrupts : Must contain an entry for each entry in - interrupts : Must contain an entry for each entry in
interrupt-names. interrupt-names.
- interrupt-names : A list which must include the following entries: - interrupt-names : A list which must include the following entries:
...@@ -22,6 +31,8 @@ Required properties: ...@@ -22,6 +31,8 @@ Required properties:
- reg-names : A list which must include the following entries: - reg-names : A list which must include the following entries:
* "lpass-lpaif" * "lpass-lpaif"
Optional properties: Optional properties:
- qcom,adsp : Phandle for the audio DSP node - qcom,adsp : Phandle for the audio DSP node
......
...@@ -48,7 +48,7 @@ DAI subnode properties: ...@@ -48,7 +48,7 @@ DAI subnode properties:
Example: Example:
rcar_sound: rcar_sound@ec500000 { rcar_sound: sound@ec500000 {
#sound-dai-cells = <1>; #sound-dai-cells = <1>;
compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2"; compatible = "renesas,rcar_sound-r8a7791", "renesas,rcar_sound-gen2";
reg = <0 0xec500000 0 0x1000>, /* SCU */ reg = <0 0xec500000 0 0x1000>, /* SCU */
......
...@@ -18,6 +18,7 @@ Required properties: ...@@ -18,6 +18,7 @@ Required properties:
Optional properties: Optional properties:
- realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin. - realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin.
- realtek,reset-gpio : The GPIO that controls the CODEC's RESET pin.
- realtek,in1-differential - realtek,in1-differential
- realtek,in2-differential - realtek,in2-differential
...@@ -70,6 +71,7 @@ rt5677 { ...@@ -70,6 +71,7 @@ rt5677 {
realtek,pow-ldo2-gpio = realtek,pow-ldo2-gpio =
<&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>; <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
realtek,reset-gpio = <&gpio TEGRA_GPIO(BB, 3) GPIO_ACTIVE_LOW>;
realtek,in1-differential = "true"; realtek,in1-differential = "true";
realtek,gpio-config = /bits/ 8 <0 0 0 0 0 2>; /* pull up GPIO6 */ realtek,gpio-config = /bits/ 8 <0 0 0 0 0 2>; /* pull up GPIO6 */
realtek,jd2-gpio = <3>; /* Enables Jack detection for GPIO6 */ realtek,jd2-gpio = <3>; /* Enables Jack detection for GPIO6 */
......
Texas Instruments TAS5711/TAS5717/TAS5719 stereo power amplifiers
The codec is controlled through an I2C interface. It also has two other
signals that can be wired up to GPIOs: reset (strongly recommended), and
powerdown (optional).
Required properties:
- compatible: "ti,tas5711", "ti,tas5717", or "ti,tas5719"
- reg: The I2C address of the device
- #sound-dai-cells: must be equal to 0
Optional properties:
- reset-gpios: GPIO specifier for the TAS571x's active low reset line
- pdn-gpios: GPIO specifier for the TAS571x's active low powerdown line
- clocks: clock phandle for the MCLK input
- clock-names: should be "mclk"
- AVDD-supply: regulator phandle for the AVDD supply (all chips)
- DVDD-supply: regulator phandle for the DVDD supply (all chips)
- HPVDD-supply: regulator phandle for the HPVDD supply (5717/5719)
- PVDD_AB-supply: regulator phandle for the PVDD_AB supply (5717/5719)
- PVDD_CD-supply: regulator phandle for the PVDD_CD supply (5717/5719)
- PVDD_A-supply: regulator phandle for the PVDD_A supply (5711)
- PVDD_B-supply: regulator phandle for the PVDD_B supply (5711)
- PVDD_C-supply: regulator phandle for the PVDD_C supply (5711)
- PVDD_D-supply: regulator phandle for the PVDD_D supply (5711)
Example:
tas5717: audio-codec@2a {
compatible = "ti,tas5717";
reg = <0x2a>;
#sound-dai-cells = <0>;
reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
pdn-gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
clocks = <&clk_core CLK_I2S>;
clock-names = "mclk";
};
...@@ -10,9 +10,20 @@ Required properties: ...@@ -10,9 +10,20 @@ Required properties:
- reg : the I2C address of the device for I2C, the chip select - reg : the I2C address of the device for I2C, the chip select
number for SPI. number for SPI.
Optional properties:
- diff-mode: Differential output mode configuration. Default value for field
DIFF in register R8 (MODE_CONTROL_2). If absent, the default is 0, shall be:
0 = stereo
1 = mono left
2 = stereo reversed
3 = mono right
Example: Example:
codec: wm8741@1a { codec: wm8741@1a {
compatible = "wlf,wm8741"; compatible = "wlf,wm8741";
reg = <0x1a>; reg = <0x1a>;
diff-mode = <3>;
}; };
ZTE ZX296702 I2S controller
Required properties:
- compatible : Must be "zte,zx296702-i2s"
- reg : Must contain I2S core's registers location and length
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
- clock-names: "tx" for the clock to the I2S interface.
- dmas: Pairs of phandle and specifier for the DMA channel that is used by
the core. The core expects two dma channels for transmit.
- dma-names : Must be "tx" and "rx"
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:
i2s0: i2s0@0b005000 {
#sound-dai-cells = <0>;
compatible = "zte,zx296702-i2s";
reg = <0x0b005000 0x1000>;
clocks = <&lsp0clk ZX296702_I2S0_DIV>;
clock-names = "tx";
interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&dma 5>, <&dma 6>;
dma-names = "tx", "rx";
status = "okay";
};
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "zx296702_snd";
simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&sndcodec>;
simple-audio-card,frame-master = <&sndcodec>;
sndcpu: simple-audio-card,cpu {
sound-dai = <&i2s0>;
};
sndcodec: simple-audio-card,codec {
sound-dai = <&acodec>;
};
};
ZTE ZX296702 SPDIF controller
Required properties:
- compatible : Must be "zte,zx296702-spdif"
- reg : Must contain SPDIF core's registers location and length
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
- clock-names: "tx" for the clock to the SPDIF interface.
- dmas: Pairs of phandle and specifier for the DMA channel that is used by
the core. The core expects one dma channel for transmit.
- dma-names : Must be "tx"
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:
spdif0: spdif0@0b004000 {
compatible = "zte,zx296702-spdif";
reg = <0x0b004000 0x1000>;
clocks = <&lsp0clk ZX296702_SPDIF0_DIV>;
clock-names = "tx";
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&dma 4>;
dma-names = "tx";
status = "okay";
};
...@@ -54,6 +54,7 @@ cosmic Cosmic Circuits ...@@ -54,6 +54,7 @@ cosmic Cosmic Circuits
crystalfontz Crystalfontz America, Inc. crystalfontz Crystalfontz America, Inc.
dallas Maxim Integrated Products (formerly Dallas Semiconductor) dallas Maxim Integrated Products (formerly Dallas Semiconductor)
davicom DAVICOM Semiconductor, Inc. davicom DAVICOM Semiconductor, Inc.
delta Delta Electronics, Inc.
denx Denx Software Engineering denx Denx Software Engineering
digi Digi International Inc. digi Digi International Inc.
digilent Diglent, Inc. digilent Diglent, Inc.
......
...@@ -9924,6 +9924,12 @@ L: netdev@vger.kernel.org ...@@ -9924,6 +9924,12 @@ L: netdev@vger.kernel.org
S: Maintained S: Maintained
F: drivers/net/ethernet/ti/netcp* F: drivers/net/ethernet/ti/netcp*
TI TAS571X FAMILY ASoC CODEC DRIVER
M: Kevin Cernekee <cernekee@chromium.org>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Odd Fixes
F: sound/soc/codecs/tas571x*
TI TWL4030 SERIES SOC CODEC DRIVER TI TWL4030 SERIES SOC CODEC DRIVER
M: Peter Ujfalusi <peter.ujfalusi@ti.com> M: Peter Ujfalusi <peter.ujfalusi@ti.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers) L: alsa-devel@alsa-project.org (moderated for non-subscribers)
......
...@@ -465,6 +465,7 @@ static dma_cookie_t rcar_dmac_tx_submit(struct dma_async_tx_descriptor *tx) ...@@ -465,6 +465,7 @@ static dma_cookie_t rcar_dmac_tx_submit(struct dma_async_tx_descriptor *tx)
static int rcar_dmac_desc_alloc(struct rcar_dmac_chan *chan, gfp_t gfp) static int rcar_dmac_desc_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
{ {
struct rcar_dmac_desc_page *page; struct rcar_dmac_desc_page *page;
unsigned long flags;
LIST_HEAD(list); LIST_HEAD(list);
unsigned int i; unsigned int i;
...@@ -482,10 +483,10 @@ static int rcar_dmac_desc_alloc(struct rcar_dmac_chan *chan, gfp_t gfp) ...@@ -482,10 +483,10 @@ static int rcar_dmac_desc_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
list_add_tail(&desc->node, &list); list_add_tail(&desc->node, &list);
} }
spin_lock_irq(&chan->lock); spin_lock_irqsave(&chan->lock, flags);
list_splice_tail(&list, &chan->desc.free); list_splice_tail(&list, &chan->desc.free);
list_add_tail(&page->node, &chan->desc.pages); list_add_tail(&page->node, &chan->desc.pages);
spin_unlock_irq(&chan->lock); spin_unlock_irqrestore(&chan->lock, flags);
return 0; return 0;
} }
...@@ -516,6 +517,7 @@ static void rcar_dmac_desc_put(struct rcar_dmac_chan *chan, ...@@ -516,6 +517,7 @@ static void rcar_dmac_desc_put(struct rcar_dmac_chan *chan,
static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan) static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
{ {
struct rcar_dmac_desc *desc, *_desc; struct rcar_dmac_desc *desc, *_desc;
unsigned long flags;
LIST_HEAD(list); LIST_HEAD(list);
/* /*
...@@ -524,9 +526,9 @@ static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan) ...@@ -524,9 +526,9 @@ static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
* list_for_each_entry_safe, isn't safe if we release the channel lock * list_for_each_entry_safe, isn't safe if we release the channel lock
* around the rcar_dmac_desc_put() call. * around the rcar_dmac_desc_put() call.
*/ */
spin_lock_irq(&chan->lock); spin_lock_irqsave(&chan->lock, flags);
list_splice_init(&chan->desc.wait, &list); list_splice_init(&chan->desc.wait, &list);
spin_unlock_irq(&chan->lock); spin_unlock_irqrestore(&chan->lock, flags);
list_for_each_entry_safe(desc, _desc, &list, node) { list_for_each_entry_safe(desc, _desc, &list, node) {
if (async_tx_test_ack(&desc->async_tx)) { if (async_tx_test_ack(&desc->async_tx)) {
...@@ -539,9 +541,9 @@ static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan) ...@@ -539,9 +541,9 @@ static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
return; return;
/* Put the remaining descriptors back in the wait list. */ /* Put the remaining descriptors back in the wait list. */
spin_lock_irq(&chan->lock); spin_lock_irqsave(&chan->lock, flags);
list_splice(&list, &chan->desc.wait); list_splice(&list, &chan->desc.wait);
spin_unlock_irq(&chan->lock); spin_unlock_irqrestore(&chan->lock, flags);
} }
/* /*
...@@ -556,12 +558,13 @@ static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan) ...@@ -556,12 +558,13 @@ static void rcar_dmac_desc_recycle_acked(struct rcar_dmac_chan *chan)
static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan) static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan)
{ {
struct rcar_dmac_desc *desc; struct rcar_dmac_desc *desc;
unsigned long flags;
int ret; int ret;
/* Recycle acked descriptors before attempting allocation. */ /* Recycle acked descriptors before attempting allocation. */
rcar_dmac_desc_recycle_acked(chan); rcar_dmac_desc_recycle_acked(chan);
spin_lock_irq(&chan->lock); spin_lock_irqsave(&chan->lock, flags);
while (list_empty(&chan->desc.free)) { while (list_empty(&chan->desc.free)) {
/* /*
...@@ -570,17 +573,17 @@ static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan) ...@@ -570,17 +573,17 @@ static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan)
* allocated descriptors. If the allocation fails return an * allocated descriptors. If the allocation fails return an
* error. * error.
*/ */
spin_unlock_irq(&chan->lock); spin_unlock_irqrestore(&chan->lock, flags);
ret = rcar_dmac_desc_alloc(chan, GFP_NOWAIT); ret = rcar_dmac_desc_alloc(chan, GFP_NOWAIT);
if (ret < 0) if (ret < 0)
return NULL; return NULL;
spin_lock_irq(&chan->lock); spin_lock_irqsave(&chan->lock, flags);
} }
desc = list_first_entry(&chan->desc.free, struct rcar_dmac_desc, node); desc = list_first_entry(&chan->desc.free, struct rcar_dmac_desc, node);
list_del(&desc->node); list_del(&desc->node);
spin_unlock_irq(&chan->lock); spin_unlock_irqrestore(&chan->lock, flags);
return desc; return desc;
} }
...@@ -593,6 +596,7 @@ static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan) ...@@ -593,6 +596,7 @@ static struct rcar_dmac_desc *rcar_dmac_desc_get(struct rcar_dmac_chan *chan)
static int rcar_dmac_xfer_chunk_alloc(struct rcar_dmac_chan *chan, gfp_t gfp) static int rcar_dmac_xfer_chunk_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
{ {
struct rcar_dmac_desc_page *page; struct rcar_dmac_desc_page *page;
unsigned long flags;
LIST_HEAD(list); LIST_HEAD(list);
unsigned int i; unsigned int i;
...@@ -606,10 +610,10 @@ static int rcar_dmac_xfer_chunk_alloc(struct rcar_dmac_chan *chan, gfp_t gfp) ...@@ -606,10 +610,10 @@ static int rcar_dmac_xfer_chunk_alloc(struct rcar_dmac_chan *chan, gfp_t gfp)
list_add_tail(&chunk->node, &list); list_add_tail(&chunk->node, &list);
} }
spin_lock_irq(&chan->lock); spin_lock_irqsave(&chan->lock, flags);
list_splice_tail(&list, &chan->desc.chunks_free); list_splice_tail(&list, &chan->desc.chunks_free);
list_add_tail(&page->node, &chan->desc.pages); list_add_tail(&page->node, &chan->desc.pages);
spin_unlock_irq(&chan->lock); spin_unlock_irqrestore(&chan->lock, flags);
return 0; return 0;
} }
...@@ -627,9 +631,10 @@ static struct rcar_dmac_xfer_chunk * ...@@ -627,9 +631,10 @@ static struct rcar_dmac_xfer_chunk *
rcar_dmac_xfer_chunk_get(struct rcar_dmac_chan *chan) rcar_dmac_xfer_chunk_get(struct rcar_dmac_chan *chan)
{ {
struct rcar_dmac_xfer_chunk *chunk; struct rcar_dmac_xfer_chunk *chunk;
unsigned long flags;
int ret; int ret;
spin_lock_irq(&chan->lock); spin_lock_irqsave(&chan->lock, flags);
while (list_empty(&chan->desc.chunks_free)) { while (list_empty(&chan->desc.chunks_free)) {
/* /*
...@@ -638,18 +643,18 @@ rcar_dmac_xfer_chunk_get(struct rcar_dmac_chan *chan) ...@@ -638,18 +643,18 @@ rcar_dmac_xfer_chunk_get(struct rcar_dmac_chan *chan)
* allocated descriptors. If the allocation fails return an * allocated descriptors. If the allocation fails return an
* error. * error.
*/ */
spin_unlock_irq(&chan->lock); spin_unlock_irqrestore(&chan->lock, flags);
ret = rcar_dmac_xfer_chunk_alloc(chan, GFP_NOWAIT); ret = rcar_dmac_xfer_chunk_alloc(chan, GFP_NOWAIT);
if (ret < 0) if (ret < 0)
return NULL; return NULL;
spin_lock_irq(&chan->lock); spin_lock_irqsave(&chan->lock, flags);
} }
chunk = list_first_entry(&chan->desc.chunks_free, chunk = list_first_entry(&chan->desc.chunks_free,
struct rcar_dmac_xfer_chunk, node); struct rcar_dmac_xfer_chunk, node);
list_del(&chunk->node); list_del(&chunk->node);
spin_unlock_irq(&chan->lock); spin_unlock_irqrestore(&chan->lock, flags);
return chunk; return chunk;
} }
......
...@@ -78,11 +78,6 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev, ...@@ -78,11 +78,6 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,
if (ret != 0) if (ret != 0)
return ret; return ret;
ret = regmap_update_bits(regmap, ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
ARIZONA_SUBSYS_MAX_FREQ, val);
if (ret != 0)
return ret;
if (val) if (val)
return 0; return 0;
......
#ifndef __DT_APQ8016_LPASS_H
#define __DT_APQ8016_LPASS_H
#define MI2S_PRIMARY 0
#define MI2S_SECONDARY 1
#define MI2S_TERTIARY 2
#define MI2S_QUATERNARY 3
#endif /* __DT_APQ8016_LPASS_H */
#ifndef __AUDIO_JACK_EVENTS_H
#define __AUDIO_JACK_EVENTS_H
#define JACK_HEADPHONE 1
#define JACK_MICROPHONE 2
#define JACK_LINEOUT 3
#define JACK_LINEIN 4
#endif /* __AUDIO_JACK_EVENTS_H */
#ifndef __DT_TAS2552_H
#define __DT_TAS2552_H
#define TAS2552_PLL_CLKIN (0)
#define TAS2552_PDM_CLK (1)
#define TAS2552_CLK_TARGET_MASK (1)
#define TAS2552_PLL_CLKIN_MCLK ((0 << 1) | TAS2552_PLL_CLKIN)
#define TAS2552_PLL_CLKIN_BCLK ((1 << 1) | TAS2552_PLL_CLKIN)
#define TAS2552_PLL_CLKIN_IVCLKIN ((2 << 1) | TAS2552_PLL_CLKIN)
#define TAS2552_PLL_CLKIN_1_8_FIXED ((3 << 1) | TAS2552_PLL_CLKIN)
#define TAS2552_PDM_CLK_PLL ((0 << 1) | TAS2552_PDM_CLK)
#define TAS2552_PDM_CLK_IVCLKIN ((1 << 1) | TAS2552_PDM_CLK)
#define TAS2552_PDM_CLK_BCLK ((2 << 1) | TAS2552_PDM_CLK)
#define TAS2552_PDM_CLK_MCLK ((3 << 1) | TAS2552_PDM_CLK)
#endif /* __DT_TAS2552_H */
...@@ -90,11 +90,6 @@ void snd_dmaengine_pcm_set_config_from_dai_data( ...@@ -90,11 +90,6 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
* makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well. * makes sense if SND_DMAENGINE_PCM_FLAG_COMPAT is set as well.
*/ */
#define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1) #define SND_DMAENGINE_PCM_FLAG_NO_DT BIT(1)
/*
* The platforms dmaengine driver does not support reporting the amount of
* bytes that are still left to transfer.
*/
#define SND_DMAENGINE_PCM_FLAG_NO_RESIDUE BIT(2)
/* /*
* The PCM is half duplex and the DMA channel is shared between capture and * The PCM is half duplex and the DMA channel is shared between capture and
* playback. * playback.
......
...@@ -15,7 +15,6 @@ struct rt5645_platform_data { ...@@ -15,7 +15,6 @@ struct rt5645_platform_data {
/* IN2 can optionally be differential */ /* IN2 can optionally be differential */
bool in2_diff; bool in2_diff;
bool dmic_en;
unsigned int dmic1_data_pin; unsigned int dmic1_data_pin;
/* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */ /* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */
unsigned int dmic2_data_pin; unsigned int dmic2_data_pin;
...@@ -24,8 +23,6 @@ struct rt5645_platform_data { ...@@ -24,8 +23,6 @@ struct rt5645_platform_data {
unsigned int hp_det_gpio; unsigned int hp_det_gpio;
bool gpio_hp_det_active_high; bool gpio_hp_det_active_high;
/* true if codec's jd function is used */
bool en_jd_func;
unsigned int jd_mode; unsigned int jd_mode;
}; };
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include <linux/types.h> #include <linux/types.h>
#include <sound/control.h> #include <sound/control.h>
#include <sound/soc-topology.h>
#include <sound/asoc.h>
struct device; struct device;
...@@ -107,6 +109,10 @@ struct device; ...@@ -107,6 +109,10 @@ struct device;
{ .id = snd_soc_dapm_mux, .name = wname, \ { .id = snd_soc_dapm_mux, .name = wname, \
SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
.kcontrol_news = wcontrols, .num_kcontrols = 1} .kcontrol_news = wcontrols, .num_kcontrols = 1}
#define SND_SOC_DAPM_DEMUX(wname, wreg, wshift, winvert, wcontrols) \
{ .id = snd_soc_dapm_demux, .name = wname, \
SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \
.kcontrol_news = wcontrols, .num_kcontrols = 1}
/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ /* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\ #define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
...@@ -444,11 +450,15 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, ...@@ -444,11 +450,15 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm( struct snd_soc_dapm_context *snd_soc_dapm_kcontrol_dapm(
struct snd_kcontrol *kcontrol); struct snd_kcontrol *kcontrol);
int snd_soc_dapm_force_bias_level(struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level);
/* dapm widget types */ /* dapm widget types */
enum snd_soc_dapm_type { enum snd_soc_dapm_type {
snd_soc_dapm_input = 0, /* input pin */ snd_soc_dapm_input = 0, /* input pin */
snd_soc_dapm_output, /* output pin */ snd_soc_dapm_output, /* output pin */
snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */ snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */
snd_soc_dapm_demux, /* connects the input to one of multiple outputs */
snd_soc_dapm_mixer, /* mixes several analog signals together */ snd_soc_dapm_mixer, /* mixes several analog signals together */
snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */ snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */
snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */ snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */
...@@ -563,6 +573,7 @@ struct snd_soc_dapm_widget { ...@@ -563,6 +573,7 @@ struct snd_soc_dapm_widget {
int num_kcontrols; int num_kcontrols;
const struct snd_kcontrol_new *kcontrol_news; const struct snd_kcontrol_new *kcontrol_news;
struct snd_kcontrol **kcontrols; struct snd_kcontrol **kcontrols;
struct snd_soc_dobj dobj;
/* widget input and outputs */ /* widget input and outputs */
struct list_head sources; struct list_head sources;
...@@ -585,6 +596,10 @@ struct snd_soc_dapm_update { ...@@ -585,6 +596,10 @@ struct snd_soc_dapm_update {
int val; int val;
}; };
struct snd_soc_dapm_wcache {
struct snd_soc_dapm_widget *widget;
};
/* DAPM context */ /* DAPM context */
struct snd_soc_dapm_context { struct snd_soc_dapm_context {
enum snd_soc_bias_level bias_level; enum snd_soc_bias_level bias_level;
...@@ -606,6 +621,9 @@ struct snd_soc_dapm_context { ...@@ -606,6 +621,9 @@ struct snd_soc_dapm_context {
int (*set_bias_level)(struct snd_soc_dapm_context *dapm, int (*set_bias_level)(struct snd_soc_dapm_context *dapm,
enum snd_soc_bias_level level); enum snd_soc_bias_level level);
struct snd_soc_dapm_wcache path_sink_cache;
struct snd_soc_dapm_wcache path_source_cache;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_dapm; struct dentry *debugfs_dapm;
#endif #endif
...@@ -623,4 +641,35 @@ struct snd_soc_dapm_stats { ...@@ -623,4 +641,35 @@ struct snd_soc_dapm_stats {
int neighbour_checks; int neighbour_checks;
}; };
/**
* snd_soc_dapm_init_bias_level() - Initialize DAPM bias level
* @dapm: The DAPM context to initialize
* @level: The DAPM level to initialize to
*
* This function only sets the driver internal state of the DAPM level and will
* not modify the state of the device. Hence it should not be used during normal
* operation, but only to synchronize the internal state to the device state.
* E.g. during driver probe to set the DAPM level to the one corresponding with
* the power-on reset state of the device.
*
* To change the DAPM state of the device use snd_soc_dapm_set_bias_level().
*/
static inline void snd_soc_dapm_init_bias_level(
struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
{
dapm->bias_level = level;
}
/**
* snd_soc_dapm_get_bias_level() - Get current DAPM bias level
* @dapm: The context for which to get the bias level
*
* Returns: The current bias level of the passed DAPM context.
*/
static inline enum snd_soc_bias_level snd_soc_dapm_get_bias_level(
struct snd_soc_dapm_context *dapm)
{
return dapm->bias_level;
}
#endif #endif
/*
* linux/sound/soc-topology.h -- ALSA SoC Firmware Controls and DAPM
*
* Copyright (C) 2012 Texas Instruments Inc.
* Copyright (C) 2015 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Simple file API to load FW that includes mixers, coefficients, DAPM graphs,
* algorithms, equalisers, DAIs, widgets, FE caps, BE caps, codec link caps etc.
*/
#ifndef __LINUX_SND_SOC_TPLG_H
#define __LINUX_SND_SOC_TPLG_H
#include <sound/asoc.h>
#include <linux/list.h>
struct firmware;
struct snd_kcontrol;
struct snd_soc_tplg_pcm_be;
struct snd_ctl_elem_value;
struct snd_ctl_elem_info;
struct snd_soc_dapm_widget;
struct snd_soc_component;
struct snd_soc_tplg_pcm_fe;
struct snd_soc_dapm_context;
struct snd_soc_card;
/* object scan be loaded and unloaded in groups with identfying indexes */
#define SND_SOC_TPLG_INDEX_ALL 0 /* ID that matches all FW objects */
/* dynamic object type */
enum snd_soc_dobj_type {
SND_SOC_DOBJ_NONE = 0, /* object is not dynamic */
SND_SOC_DOBJ_MIXER,
SND_SOC_DOBJ_ENUM,
SND_SOC_DOBJ_BYTES,
SND_SOC_DOBJ_PCM,
SND_SOC_DOBJ_DAI_LINK,
SND_SOC_DOBJ_CODEC_LINK,
SND_SOC_DOBJ_WIDGET,
};
/* dynamic control object */
struct snd_soc_dobj_control {
struct snd_kcontrol *kcontrol;
char **dtexts;
unsigned long *dvalues;
};
/* dynamic widget object */
struct snd_soc_dobj_widget {
unsigned int kcontrol_enum:1; /* this widget is an enum kcontrol */
};
/* dynamic PCM DAI object */
struct snd_soc_dobj_pcm_dai {
struct snd_soc_tplg_pcm_dai *pd;
unsigned int count;
};
/* generic dynamic object - all dynamic objects belong to this struct */
struct snd_soc_dobj {
enum snd_soc_dobj_type type;
unsigned int index; /* objects can belong in different groups */
struct list_head list;
struct snd_soc_tplg_ops *ops;
union {
struct snd_soc_dobj_control control;
struct snd_soc_dobj_widget widget;
struct snd_soc_dobj_pcm_dai pcm_dai;
};
void *private; /* core does not touch this */
};
/*
* Kcontrol operations - used to map handlers onto firmware based controls.
*/
struct snd_soc_tplg_kcontrol_ops {
u32 id;
int (*get)(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int (*put)(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int (*info)(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
};
/*
* DAPM widget event handlers - used to map handlers onto widgets.
*/
struct snd_soc_tplg_widget_events {
u16 type;
int (*event_handler)(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event);
};
/*
* Public API - Used by component drivers to load and unload dynamic objects
* and their resources.
*/
struct snd_soc_tplg_ops {
/* external kcontrol init - used for any driver specific init */
int (*control_load)(struct snd_soc_component *,
struct snd_kcontrol_new *, struct snd_soc_tplg_ctl_hdr *);
int (*control_unload)(struct snd_soc_component *,
struct snd_soc_dobj *);
/* external widget init - used for any driver specific init */
int (*widget_load)(struct snd_soc_component *,
struct snd_soc_dapm_widget *,
struct snd_soc_tplg_dapm_widget *);
int (*widget_unload)(struct snd_soc_component *,
struct snd_soc_dobj *);
/* FE - used for any driver specific init */
int (*pcm_dai_load)(struct snd_soc_component *,
struct snd_soc_tplg_pcm_dai *pcm_dai, int num_fe);
int (*pcm_dai_unload)(struct snd_soc_component *,
struct snd_soc_dobj *);
/* callback to handle vendor bespoke data */
int (*vendor_load)(struct snd_soc_component *,
struct snd_soc_tplg_hdr *);
int (*vendor_unload)(struct snd_soc_component *,
struct snd_soc_tplg_hdr *);
/* completion - called at completion of firmware loading */
void (*complete)(struct snd_soc_component *);
/* manifest - optional to inform component of manifest */
int (*manifest)(struct snd_soc_component *,
struct snd_soc_tplg_manifest *);
/* bespoke kcontrol handlers available for binding */
const struct snd_soc_tplg_kcontrol_ops *io_ops;
int io_ops_count;
};
/* gets a pointer to data from the firmware block header */
static inline const void *snd_soc_tplg_get_data(struct snd_soc_tplg_hdr *hdr)
{
const void *ptr = hdr;
return ptr + sizeof(*hdr);
}
/* Dynamic Object loading and removal for component drivers */
int snd_soc_tplg_component_load(struct snd_soc_component *comp,
struct snd_soc_tplg_ops *ops, const struct firmware *fw,
u32 index);
int snd_soc_tplg_component_remove(struct snd_soc_component *comp, u32 index);
/* Widget removal - widgets also removed wth component API */
void snd_soc_tplg_widget_remove(struct snd_soc_dapm_widget *w);
void snd_soc_tplg_widget_remove_all(struct snd_soc_dapm_context *dapm,
u32 index);
/* Binds event handlers to dynamic widgets */
int snd_soc_tplg_widget_bind_event(struct snd_soc_dapm_widget *w,
const struct snd_soc_tplg_widget_events *events, int num_events,
u16 event_type);
#endif
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <sound/compress_driver.h> #include <sound/compress_driver.h>
#include <sound/control.h> #include <sound/control.h>
#include <sound/ac97_codec.h> #include <sound/ac97_codec.h>
#include <sound/soc-topology.h>
/* /*
* Convenience kcontrol builders * Convenience kcontrol builders
...@@ -190,8 +191,12 @@ ...@@ -190,8 +191,12 @@
#define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xitems, xtexts, xvalues) \ #define SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xitems, xtexts, xvalues) \
{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
.mask = xmask, .items = xitems, .texts = xtexts, .values = xvalues} .mask = xmask, .items = xitems, .texts = xtexts, .values = xvalues}
#define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xnitmes, xtexts, xvalues) \ #define SOC_VALUE_ENUM_SINGLE(xreg, xshift, xmask, xitems, xtexts, xvalues) \
SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xnitmes, xtexts, xvalues) SOC_VALUE_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xitems, xtexts, xvalues)
#define SOC_VALUE_ENUM_SINGLE_AUTODISABLE(xreg, xshift, xmask, xitems, xtexts, xvalues) \
{ .reg = xreg, .shift_l = xshift, .shift_r = xshift, \
.mask = xmask, .items = xitems, .texts = xtexts, \
.values = xvalues, .autodisable = 1}
#define SOC_ENUM_SINGLE_VIRT(xitems, xtexts) \ #define SOC_ENUM_SINGLE_VIRT(xitems, xtexts) \
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, xitems, xtexts) SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, xitems, xtexts)
#define SOC_ENUM(xname, xenum) \ #define SOC_ENUM(xname, xenum) \
...@@ -312,6 +317,11 @@ ...@@ -312,6 +317,11 @@
ARRAY_SIZE(xtexts), xtexts, xvalues) ARRAY_SIZE(xtexts), xtexts, xvalues)
#define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \ #define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues) SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues)
#define SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
const struct soc_enum name = SOC_VALUE_ENUM_SINGLE_AUTODISABLE(xreg, \
xshift, xmask, ARRAY_SIZE(xtexts), xtexts, xvalues)
#define SOC_ENUM_SINGLE_VIRT_DECL(name, xtexts) \ #define SOC_ENUM_SINGLE_VIRT_DECL(name, xtexts) \
const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts) const struct soc_enum name = SOC_ENUM_SINGLE_VIRT(ARRAY_SIZE(xtexts), xtexts)
...@@ -767,6 +777,9 @@ struct snd_soc_component { ...@@ -767,6 +777,9 @@ struct snd_soc_component {
struct mutex io_mutex; struct mutex io_mutex;
/* attached dynamic objects */
struct list_head dobj_list;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_root; struct dentry *debugfs_root;
#endif #endif
...@@ -819,7 +832,7 @@ struct snd_soc_codec { ...@@ -819,7 +832,7 @@ struct snd_soc_codec {
/* component */ /* component */
struct snd_soc_component component; struct snd_soc_component component;
/* dapm */ /* Don't access this directly, use snd_soc_codec_get_dapm() */
struct snd_soc_dapm_context dapm; struct snd_soc_dapm_context dapm;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
...@@ -961,6 +974,24 @@ struct snd_soc_dai_link { ...@@ -961,6 +974,24 @@ struct snd_soc_dai_link {
enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */ enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */
/* codec/machine specific init - e.g. add machine controls */
int (*init)(struct snd_soc_pcm_runtime *rtd);
/* optional hw_params re-writing for BE and FE sync */
int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params);
/* machine stream operations */
const struct snd_soc_ops *ops;
const struct snd_soc_compr_ops *compr_ops;
/* For unidirectional dai links */
bool playback_only;
bool capture_only;
/* Mark this pcm with non atomic ops */
bool nonatomic;
/* Keep DAI active over suspend */ /* Keep DAI active over suspend */
unsigned int ignore_suspend:1; unsigned int ignore_suspend:1;
...@@ -969,9 +1000,6 @@ struct snd_soc_dai_link { ...@@ -969,9 +1000,6 @@ struct snd_soc_dai_link {
unsigned int symmetric_channels:1; unsigned int symmetric_channels:1;
unsigned int symmetric_samplebits:1; unsigned int symmetric_samplebits:1;
/* Mark this pcm with non atomic ops */
bool nonatomic;
/* Do not create a PCM for this DAI link (Backend link) */ /* Do not create a PCM for this DAI link (Backend link) */
unsigned int no_pcm:1; unsigned int no_pcm:1;
...@@ -982,23 +1010,11 @@ struct snd_soc_dai_link { ...@@ -982,23 +1010,11 @@ struct snd_soc_dai_link {
unsigned int dpcm_capture:1; unsigned int dpcm_capture:1;
unsigned int dpcm_playback:1; unsigned int dpcm_playback:1;
/* DPCM used FE & BE merged format */
unsigned int dpcm_merged_format:1;
/* pmdown_time is ignored at stop */ /* pmdown_time is ignored at stop */
unsigned int ignore_pmdown_time:1; unsigned int ignore_pmdown_time:1;
/* codec/machine specific init - e.g. add machine controls */
int (*init)(struct snd_soc_pcm_runtime *rtd);
/* optional hw_params re-writing for BE and FE sync */
int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params);
/* machine stream operations */
const struct snd_soc_ops *ops;
const struct snd_soc_compr_ops *compr_ops;
/* For unidirectional dai links */
bool playback_only;
bool capture_only;
}; };
struct snd_soc_codec_conf { struct snd_soc_codec_conf {
...@@ -1111,6 +1127,9 @@ struct snd_soc_card { ...@@ -1111,6 +1127,9 @@ struct snd_soc_card {
struct list_head dapm_list; struct list_head dapm_list;
struct list_head dapm_dirty; struct list_head dapm_dirty;
/* attached dynamic objects */
struct list_head dobj_list;
/* Generic DAPM context for the card */ /* Generic DAPM context for the card */
struct snd_soc_dapm_context dapm; struct snd_soc_dapm_context dapm;
struct snd_soc_dapm_stats dapm_stats; struct snd_soc_dapm_stats dapm_stats;
...@@ -1170,6 +1189,7 @@ struct soc_mixer_control { ...@@ -1170,6 +1189,7 @@ struct soc_mixer_control {
unsigned int sign_bit; unsigned int sign_bit;
unsigned int invert:1; unsigned int invert:1;
unsigned int autodisable:1; unsigned int autodisable:1;
struct snd_soc_dobj dobj;
}; };
struct soc_bytes { struct soc_bytes {
...@@ -1180,6 +1200,8 @@ struct soc_bytes { ...@@ -1180,6 +1200,8 @@ struct soc_bytes {
struct soc_bytes_ext { struct soc_bytes_ext {
int max; int max;
struct snd_soc_dobj dobj;
/* used for TLV byte control */ /* used for TLV byte control */
int (*get)(unsigned int __user *bytes, unsigned int size); int (*get)(unsigned int __user *bytes, unsigned int size);
int (*put)(const unsigned int __user *bytes, unsigned int size); int (*put)(const unsigned int __user *bytes, unsigned int size);
...@@ -1200,6 +1222,8 @@ struct soc_enum { ...@@ -1200,6 +1222,8 @@ struct soc_enum {
unsigned int mask; unsigned int mask;
const char * const *texts; const char * const *texts;
const unsigned int *values; const unsigned int *values;
unsigned int autodisable:1;
struct snd_soc_dobj dobj;
}; };
/** /**
...@@ -1281,6 +1305,58 @@ static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm( ...@@ -1281,6 +1305,58 @@ static inline struct snd_soc_dapm_context *snd_soc_component_get_dapm(
return component->dapm_ptr; return component->dapm_ptr;
} }
/**
* snd_soc_codec_get_dapm() - Returns the DAPM context for the CODEC
* @codec: The CODEC for which to get the DAPM context
*
* Note: Use this function instead of directly accessing the CODEC's dapm field
*/
static inline struct snd_soc_dapm_context *snd_soc_codec_get_dapm(
struct snd_soc_codec *codec)
{
return &codec->dapm;
}
/**
* snd_soc_dapm_init_bias_level() - Initialize CODEC DAPM bias level
* @dapm: The CODEC for which to initialize the DAPM bias level
* @level: The DAPM level to initialize to
*
* Initializes the CODEC DAPM bias level. See snd_soc_dapm_init_bias_level().
*/
static inline void snd_soc_codec_init_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
snd_soc_dapm_init_bias_level(snd_soc_codec_get_dapm(codec), level);
}
/**
* snd_soc_dapm_get_bias_level() - Get current CODEC DAPM bias level
* @codec: The CODEC for which to get the DAPM bias level
*
* Returns: The current DAPM bias level of the CODEC.
*/
static inline enum snd_soc_bias_level snd_soc_codec_get_bias_level(
struct snd_soc_codec *codec)
{
return snd_soc_dapm_get_bias_level(snd_soc_codec_get_dapm(codec));
}
/**
* snd_soc_codec_force_bias_level() - Set the CODEC DAPM bias level
* @codec: The CODEC for which to set the level
* @level: The level to set to
*
* Forces the CODEC bias level to a specific state. See
* snd_soc_dapm_force_bias_level().
*/
static inline int snd_soc_codec_force_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
return snd_soc_dapm_force_bias_level(snd_soc_codec_get_dapm(codec),
level);
}
/** /**
* snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
* @kcontrol: The kcontrol * @kcontrol: The kcontrol
......
...@@ -31,12 +31,7 @@ ...@@ -31,12 +31,7 @@
* ~(sizeof(unsigned int) - 1)) .... * ~(sizeof(unsigned int) - 1)) ....
*/ */
#define SNDRV_CTL_TLVT_CONTAINER 0 /* one level down - group of TLVs */ #include <uapi/sound/tlv.h>
#define SNDRV_CTL_TLVT_DB_SCALE 1 /* dB scale */
#define SNDRV_CTL_TLVT_DB_LINEAR 2 /* linear volume */
#define SNDRV_CTL_TLVT_DB_RANGE 3 /* dB range container */
#define SNDRV_CTL_TLVT_DB_MINMAX 4 /* dB scale with min/max */
#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5 /* dB scale with min/max with mute */
#define TLV_ITEM(type, ...) \ #define TLV_ITEM(type, ...) \
(type), TLV_LENGTH(__VA_ARGS__), __VA_ARGS__ (type), TLV_LENGTH(__VA_ARGS__), __VA_ARGS__
...@@ -90,12 +85,4 @@ ...@@ -90,12 +85,4 @@
#define TLV_DB_GAIN_MUTE -9999999 #define TLV_DB_GAIN_MUTE -9999999
/*
* channel-mapping TLV items
* TLV length must match with num_channels
*/
#define SNDRV_CTL_TLVT_CHMAP_FIXED 0x101 /* fixed channel position */
#define SNDRV_CTL_TLVT_CHMAP_VAR 0x102 /* channels freely swappable */
#define SNDRV_CTL_TLVT_CHMAP_PAIRED 0x103 /* pair-wise swappable */
#endif /* __SOUND_TLV_H */ #endif /* __SOUND_TLV_H */
/*
* uapi/sound/asoc.h -- ALSA SoC Firmware Controls and DAPM
*
* Copyright (C) 2012 Texas Instruments Inc.
* Copyright (C) 2015 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Simple file API to load FW that includes mixers, coefficients, DAPM graphs,
* algorithms, equalisers, DAIs, widgets etc.
*/
#ifndef __LINUX_UAPI_SND_ASOC_H
#define __LINUX_UAPI_SND_ASOC_H
#include <linux/types.h>
#include <sound/asound.h>
/*
* Maximum number of channels topology kcontrol can represent.
*/
#define SND_SOC_TPLG_MAX_CHAN 8
/*
* Maximum number of PCM formats capability
*/
#define SND_SOC_TPLG_MAX_FORMATS 16
/*
* Maximum number of PCM stream configs
*/
#define SND_SOC_TPLG_STREAM_CONFIG_MAX 8
/* individual kcontrol info types - can be mixed with other types */
#define SND_SOC_TPLG_CTL_VOLSW 1
#define SND_SOC_TPLG_CTL_VOLSW_SX 2
#define SND_SOC_TPLG_CTL_VOLSW_XR_SX 3
#define SND_SOC_TPLG_CTL_ENUM 4
#define SND_SOC_TPLG_CTL_BYTES 5
#define SND_SOC_TPLG_CTL_ENUM_VALUE 6
#define SND_SOC_TPLG_CTL_RANGE 7
#define SND_SOC_TPLG_CTL_STROBE 8
/* individual widget kcontrol info types - can be mixed with other types */
#define SND_SOC_TPLG_DAPM_CTL_VOLSW 64
#define SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE 65
#define SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT 66
#define SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE 67
#define SND_SOC_TPLG_DAPM_CTL_PIN 68
/* DAPM widget types - add new items to the end */
#define SND_SOC_TPLG_DAPM_INPUT 0
#define SND_SOC_TPLG_DAPM_OUTPUT 1
#define SND_SOC_TPLG_DAPM_MUX 2
#define SND_SOC_TPLG_DAPM_MIXER 3
#define SND_SOC_TPLG_DAPM_PGA 4
#define SND_SOC_TPLG_DAPM_OUT_DRV 5
#define SND_SOC_TPLG_DAPM_ADC 6
#define SND_SOC_TPLG_DAPM_DAC 7
#define SND_SOC_TPLG_DAPM_SWITCH 8
#define SND_SOC_TPLG_DAPM_PRE 9
#define SND_SOC_TPLG_DAPM_POST 10
#define SND_SOC_TPLG_DAPM_AIF_IN 11
#define SND_SOC_TPLG_DAPM_AIF_OUT 12
#define SND_SOC_TPLG_DAPM_DAI_IN 13
#define SND_SOC_TPLG_DAPM_DAI_OUT 14
#define SND_SOC_TPLG_DAPM_DAI_LINK 15
#define SND_SOC_TPLG_DAPM_LAST SND_SOC_TPLG_DAPM_DAI_LINK
/* Header magic number and string sizes */
#define SND_SOC_TPLG_MAGIC 0x41536F43 /* ASoC */
/* string sizes */
#define SND_SOC_TPLG_NUM_TEXTS 16
/* ABI version */
#define SND_SOC_TPLG_ABI_VERSION 0x2
/* Max size of TLV data */
#define SND_SOC_TPLG_TLV_SIZE 32
/*
* File and Block header data types.
* Add new generic and vendor types to end of list.
* Generic types are handled by the core whilst vendors types are passed
* to the component drivers for handling.
*/
#define SND_SOC_TPLG_TYPE_MIXER 1
#define SND_SOC_TPLG_TYPE_BYTES 2
#define SND_SOC_TPLG_TYPE_ENUM 3
#define SND_SOC_TPLG_TYPE_DAPM_GRAPH 4
#define SND_SOC_TPLG_TYPE_DAPM_WIDGET 5
#define SND_SOC_TPLG_TYPE_DAI_LINK 6
#define SND_SOC_TPLG_TYPE_PCM 7
#define SND_SOC_TPLG_TYPE_MANIFEST 8
#define SND_SOC_TPLG_TYPE_CODEC_LINK 9
#define SND_SOC_TPLG_TYPE_MAX SND_SOC_TPLG_TYPE_CODEC_LINK
/* vendor block IDs - please add new vendor types to end */
#define SND_SOC_TPLG_TYPE_VENDOR_FW 1000
#define SND_SOC_TPLG_TYPE_VENDOR_CONFIG 1001
#define SND_SOC_TPLG_TYPE_VENDOR_COEFF 1002
#define SND_SOC_TPLG_TYPEVENDOR_CODEC 1003
#define SND_SOC_TPLG_STREAM_PLAYBACK 0
#define SND_SOC_TPLG_STREAM_CAPTURE 1
/*
* Block Header.
* This header preceeds all object and object arrays below.
*/
struct snd_soc_tplg_hdr {
__le32 magic; /* magic number */
__le32 abi; /* ABI version */
__le32 version; /* optional vendor specific version details */
__le32 type; /* SND_SOC_TPLG_TYPE_ */
__le32 size; /* size of this structure */
__le32 vendor_type; /* optional vendor specific type info */
__le32 payload_size; /* data bytes, excluding this header */
__le32 index; /* identifier for block */
__le32 count; /* number of elements in block */
} __attribute__((packed));
/*
* Private data.
* All topology objects may have private data that can be used by the driver or
* firmware. Core will ignore this data.
*/
struct snd_soc_tplg_private {
__le32 size; /* in bytes of private data */
char data[0];
} __attribute__((packed));
/*
* Kcontrol TLV data.
*/
struct snd_soc_tplg_ctl_tlv {
__le32 size; /* in bytes aligned to 4 */
__le32 numid; /* control element numeric identification */
__le32 count; /* number of elem in data array */
__le32 data[SND_SOC_TPLG_TLV_SIZE];
} __attribute__((packed));
/*
* Kcontrol channel data
*/
struct snd_soc_tplg_channel {
__le32 size; /* in bytes of this structure */
__le32 reg;
__le32 shift;
__le32 id; /* ID maps to Left, Right, LFE etc */
} __attribute__((packed));
/*
* Kcontrol Operations IDs
*/
struct snd_soc_tplg_kcontrol_ops_id {
__le32 get;
__le32 put;
__le32 info;
} __attribute__((packed));
/*
* kcontrol header
*/
struct snd_soc_tplg_ctl_hdr {
__le32 size; /* in bytes of this structure */
__le32 type;
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
__le32 access;
struct snd_soc_tplg_kcontrol_ops_id ops;
__le32 tlv_size; /* non zero means control has TLV data */
} __attribute__((packed));
/*
* Stream Capabilities
*/
struct snd_soc_tplg_stream_caps {
__le32 size; /* in bytes of this structure */
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
__le64 formats[SND_SOC_TPLG_MAX_FORMATS]; /* supported formats SNDRV_PCM_FMTBIT_* */
__le32 rates; /* supported rates SNDRV_PCM_RATE_* */
__le32 rate_min; /* min rate */
__le32 rate_max; /* max rate */
__le32 channels_min; /* min channels */
__le32 channels_max; /* max channels */
__le32 periods_min; /* min number of periods */
__le32 periods_max; /* max number of periods */
__le32 period_size_min; /* min period size bytes */
__le32 period_size_max; /* max period size bytes */
__le32 buffer_size_min; /* min buffer size bytes */
__le32 buffer_size_max; /* max buffer size bytes */
} __attribute__((packed));
/*
* FE or BE Stream configuration supported by SW/FW
*/
struct snd_soc_tplg_stream {
__le32 size; /* in bytes of this structure */
__le64 format; /* SNDRV_PCM_FMTBIT_* */
__le32 rate; /* SNDRV_PCM_RATE_* */
__le32 period_bytes; /* size of period in bytes */
__le32 buffer_bytes; /* size of buffer in bytes */
__le32 channels; /* channels */
__le32 tdm_slot; /* optional BE bitmask of supported TDM slots */
__le32 dai_fmt; /* SND_SOC_DAIFMT_ */
} __attribute__((packed));
/*
* Duplex stream configuration supported by SW/FW.
*/
struct snd_soc_tplg_stream_config {
__le32 size; /* in bytes of this structure */
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
struct snd_soc_tplg_stream playback;
struct snd_soc_tplg_stream capture;
} __attribute__((packed));
/*
* Manifest. List totals for each payload type. Not used in parsing, but will
* be passed to the component driver before any other objects in order for any
* global componnent resource allocations.
*
* File block representation for manifest :-
* +-----------------------------------+----+
* | struct snd_soc_tplg_hdr | 1 |
* +-----------------------------------+----+
* | struct snd_soc_tplg_manifest | 1 |
* +-----------------------------------+----+
*/
struct snd_soc_tplg_manifest {
__le32 size; /* in bytes of this structure */
__le32 control_elems; /* number of control elements */
__le32 widget_elems; /* number of widget elements */
__le32 graph_elems; /* number of graph elements */
__le32 dai_elems; /* number of DAI elements */
__le32 dai_link_elems; /* number of DAI link elements */
} __attribute__((packed));
/*
* Mixer kcontrol.
*
* File block representation for mixer kcontrol :-
* +-----------------------------------+----+
* | struct snd_soc_tplg_hdr | 1 |
* +-----------------------------------+----+
* | struct snd_soc_tplg_mixer_control | N |
* +-----------------------------------+----+
*/
struct snd_soc_tplg_mixer_control {
struct snd_soc_tplg_ctl_hdr hdr;
__le32 size; /* in bytes of this structure */
__le32 min;
__le32 max;
__le32 platform_max;
__le32 invert;
__le32 num_channels;
struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN];
struct snd_soc_tplg_ctl_tlv tlv;
struct snd_soc_tplg_private priv;
} __attribute__((packed));
/*
* Enumerated kcontrol
*
* File block representation for enum kcontrol :-
* +-----------------------------------+----+
* | struct snd_soc_tplg_hdr | 1 |
* +-----------------------------------+----+
* | struct snd_soc_tplg_enum_control | N |
* +-----------------------------------+----+
*/
struct snd_soc_tplg_enum_control {
struct snd_soc_tplg_ctl_hdr hdr;
__le32 size; /* in bytes of this structure */
__le32 num_channels;
struct snd_soc_tplg_channel channel[SND_SOC_TPLG_MAX_CHAN];
__le32 items;
__le32 mask;
__le32 count;
char texts[SND_SOC_TPLG_NUM_TEXTS][SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
__le32 values[SND_SOC_TPLG_NUM_TEXTS * SNDRV_CTL_ELEM_ID_NAME_MAXLEN / 4];
struct snd_soc_tplg_private priv;
} __attribute__((packed));
/*
* Bytes kcontrol
*
* File block representation for bytes kcontrol :-
* +-----------------------------------+----+
* | struct snd_soc_tplg_hdr | 1 |
* +-----------------------------------+----+
* | struct snd_soc_tplg_bytes_control | N |
* +-----------------------------------+----+
*/
struct snd_soc_tplg_bytes_control {
struct snd_soc_tplg_ctl_hdr hdr;
__le32 size; /* in bytes of this structure */
__le32 max;
__le32 mask;
__le32 base;
__le32 num_regs;
struct snd_soc_tplg_private priv;
} __attribute__((packed));
/*
* DAPM Graph Element
*
* File block representation for DAPM graph elements :-
* +-------------------------------------+----+
* | struct snd_soc_tplg_hdr | 1 |
* +-------------------------------------+----+
* | struct snd_soc_tplg_dapm_graph_elem | N |
* +-------------------------------------+----+
*/
struct snd_soc_tplg_dapm_graph_elem {
char sink[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
char control[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
char source[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
} __attribute__((packed));
/*
* DAPM Widget.
*
* File block representation for DAPM widget :-
* +-------------------------------------+-----+
* | struct snd_soc_tplg_hdr | 1 |
* +-------------------------------------+-----+
* | struct snd_soc_tplg_dapm_widget | N |
* +-------------------------------------+-----+
* | struct snd_soc_tplg_enum_control | 0|1 |
* | struct snd_soc_tplg_mixer_control | 0|N |
* +-------------------------------------+-----+
*
* Optional enum or mixer control can be appended to the end of each widget
* in the block.
*/
struct snd_soc_tplg_dapm_widget {
__le32 size; /* in bytes of this structure */
__le32 id; /* SND_SOC_DAPM_CTL */
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
char sname[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
__le32 reg; /* negative reg = no direct dapm */
__le32 shift; /* bits to shift */
__le32 mask; /* non-shifted mask */
__u32 invert; /* invert the power bit */
__u32 ignore_suspend; /* kept enabled over suspend */
__u16 event_flags;
__u16 event_type;
__u16 num_kcontrols;
struct snd_soc_tplg_private priv;
/*
* kcontrols that relate to this widget
* follow here after widget private data
*/
} __attribute__((packed));
struct snd_soc_tplg_pcm_cfg_caps {
struct snd_soc_tplg_stream_caps caps;
struct snd_soc_tplg_stream_config configs[SND_SOC_TPLG_STREAM_CONFIG_MAX];
__le32 num_configs; /* number of configs */
} __attribute__((packed));
/*
* Describes SW/FW specific features of PCM or DAI link.
*
* File block representation for PCM/DAI-Link :-
* +-----------------------------------+-----+
* | struct snd_soc_tplg_hdr | 1 |
* +-----------------------------------+-----+
* | struct snd_soc_tplg_dapm_pcm_dai | N |
* +-----------------------------------+-----+
*/
struct snd_soc_tplg_pcm_dai {
__le32 size; /* in bytes of this structure */
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
__le32 id; /* unique ID - used to match */
__le32 playback; /* supports playback mode */
__le32 capture; /* supports capture mode */
__le32 compress; /* 1 = compressed; 0 = PCM */
struct snd_soc_tplg_pcm_cfg_caps capconf[2]; /* capabilities and configs */
} __attribute__((packed));
#endif
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __UAPI_SOUND_TLV_H
#define __UAPI_SOUND_TLV_H
#define SNDRV_CTL_TLVT_CONTAINER 0 /* one level down - group of TLVs */
#define SNDRV_CTL_TLVT_DB_SCALE 1 /* dB scale */
#define SNDRV_CTL_TLVT_DB_LINEAR 2 /* linear volume */
#define SNDRV_CTL_TLVT_DB_RANGE 3 /* dB range container */
#define SNDRV_CTL_TLVT_DB_MINMAX 4 /* dB scale with min/max */
#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5 /* dB scale with min/max with mute */
/*
* channel-mapping TLV items
* TLV length must match with num_channels
*/
#define SNDRV_CTL_TLVT_CHMAP_FIXED 0x101 /* fixed channel position */
#define SNDRV_CTL_TLVT_CHMAP_VAR 0x102 /* channels freely swappable */
#define SNDRV_CTL_TLVT_CHMAP_PAIRED 0x103 /* pair-wise swappable */
#endif
...@@ -57,6 +57,7 @@ source "sound/soc/tegra/Kconfig" ...@@ -57,6 +57,7 @@ source "sound/soc/tegra/Kconfig"
source "sound/soc/txx9/Kconfig" source "sound/soc/txx9/Kconfig"
source "sound/soc/ux500/Kconfig" source "sound/soc/ux500/Kconfig"
source "sound/soc/xtensa/Kconfig" source "sound/soc/xtensa/Kconfig"
source "sound/soc/zte/Kconfig"
# Supported codecs # Supported codecs
source "sound/soc/codecs/Kconfig" source "sound/soc/codecs/Kconfig"
......
snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o soc-devres.o soc-ops.o snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o soc-devres.o soc-ops.o
snd-soc-core-objs += soc-topology.o
ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),) ifneq ($(CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM),)
snd-soc-core-objs += soc-generic-dmaengine-pcm.o snd-soc-core-objs += soc-generic-dmaengine-pcm.o
...@@ -38,3 +39,4 @@ obj-$(CONFIG_SND_SOC) += tegra/ ...@@ -38,3 +39,4 @@ obj-$(CONFIG_SND_SOC) += tegra/
obj-$(CONFIG_SND_SOC) += txx9/ obj-$(CONFIG_SND_SOC) += txx9/
obj-$(CONFIG_SND_SOC) += ux500/ obj-$(CONFIG_SND_SOC) += ux500/
obj-$(CONFIG_SND_SOC) += xtensa/ obj-$(CONFIG_SND_SOC) += xtensa/
obj-$(CONFIG_SND_SOC) += zte/
...@@ -6,27 +6,22 @@ config SND_ATMEL_SOC ...@@ -6,27 +6,22 @@ config SND_ATMEL_SOC
the ATMEL SSC interface. You will also need the ATMEL SSC interface. You will also need
to select the audio interfaces to support below. to select the audio interfaces to support below.
if SND_ATMEL_SOC
config SND_ATMEL_SOC_PDC config SND_ATMEL_SOC_PDC
tristate bool
depends on SND_ATMEL_SOC
config SND_ATMEL_SOC_DMA config SND_ATMEL_SOC_DMA
tristate bool
depends on SND_ATMEL_SOC
select SND_SOC_GENERIC_DMAENGINE_PCM select SND_SOC_GENERIC_DMAENGINE_PCM
config SND_ATMEL_SOC_SSC config SND_ATMEL_SOC_SSC
tristate tristate
depends on SND_ATMEL_SOC
help
Say Y or M if you want to add support for codecs the
ATMEL SSC interface. You will also needs to select the individual
machine drivers to support below.
config SND_AT91_SOC_SAM9G20_WM8731 config SND_AT91_SOC_SAM9G20_WM8731
tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
depends on ARCH_AT91 || COMPILE_TEST depends on ARCH_AT91 || COMPILE_TEST
depends on ATMEL_SSC && SND_ATMEL_SOC && SND_SOC_I2C_AND_SPI depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI
select SND_ATMEL_SOC_PDC select SND_ATMEL_SOC_PDC
select SND_ATMEL_SOC_SSC select SND_ATMEL_SOC_SSC
select SND_SOC_WM8731 select SND_SOC_WM8731
...@@ -37,7 +32,7 @@ config SND_AT91_SOC_SAM9G20_WM8731 ...@@ -37,7 +32,7 @@ config SND_AT91_SOC_SAM9G20_WM8731
config SND_ATMEL_SOC_WM8904 config SND_ATMEL_SOC_WM8904
tristate "Atmel ASoC driver for boards using WM8904 codec" tristate "Atmel ASoC driver for boards using WM8904 codec"
depends on ARCH_AT91 || COMPILE_TEST depends on ARCH_AT91 || COMPILE_TEST
depends on ATMEL_SSC && SND_ATMEL_SOC && I2C depends on ATMEL_SSC && I2C
select SND_ATMEL_SOC_SSC select SND_ATMEL_SOC_SSC
select SND_ATMEL_SOC_DMA select SND_ATMEL_SOC_DMA
select SND_SOC_WM8904 select SND_SOC_WM8904
...@@ -48,10 +43,11 @@ config SND_ATMEL_SOC_WM8904 ...@@ -48,10 +43,11 @@ config SND_ATMEL_SOC_WM8904
config SND_AT91_SOC_SAM9X5_WM8731 config SND_AT91_SOC_SAM9X5_WM8731
tristate "SoC Audio support for WM8731-based at91sam9x5 board" tristate "SoC Audio support for WM8731-based at91sam9x5 board"
depends on ARCH_AT91 || COMPILE_TEST depends on ARCH_AT91 || COMPILE_TEST
depends on ATMEL_SSC && SND_ATMEL_SOC && SND_SOC_I2C_AND_SPI depends on ATMEL_SSC && SND_SOC_I2C_AND_SPI
select SND_ATMEL_SOC_SSC select SND_ATMEL_SOC_SSC
select SND_ATMEL_SOC_DMA select SND_ATMEL_SOC_DMA
select SND_SOC_WM8731 select SND_SOC_WM8731
help help
Say Y if you want to add support for audio SoC on an Say Y if you want to add support for audio SoC on an
at91sam9x5 based board that is using WM8731 codec. at91sam9x5 based board that is using WM8731 codec.
endif
# AT91 Platform Support # AT91 Platform Support
snd-soc-atmel-pcm-pdc-objs := atmel-pcm-pdc.o snd-soc-atmel-pcm-$(CONFIG_SND_ATMEL_SOC_PDC) := atmel-pcm-pdc.o
snd-soc-atmel-pcm-dma-objs := atmel-pcm-dma.o snd-soc-atmel-pcm-$(CONFIG_SND_ATMEL_SOC_DMA) += atmel-pcm-dma.o
snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o $(snd-soc-atmel-pcm-y)
obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o
obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
# AT91 Machine Support # AT91 Machine Support
......
...@@ -124,8 +124,7 @@ static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = { ...@@ -124,8 +124,7 @@ static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = {
int atmel_pcm_dma_platform_register(struct device *dev) int atmel_pcm_dma_platform_register(struct device *dev)
{ {
return snd_dmaengine_pcm_register(dev, &atmel_dmaengine_pcm_config, return snd_dmaengine_pcm_register(dev, &atmel_dmaengine_pcm_config, 0);
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
} }
EXPORT_SYMBOL(atmel_pcm_dma_platform_register); EXPORT_SYMBOL(atmel_pcm_dma_platform_register);
......
...@@ -95,8 +95,9 @@ static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = { ...@@ -95,8 +95,9 @@ static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = {
static const struct snd_soc_dapm_route intercon[] = { static const struct snd_soc_dapm_route intercon[] = {
/* speaker connected to LHPOUT */ /* speaker connected to LHPOUT/RHPOUT */
{"Ext Spk", NULL, "LHPOUT"}, {"Ext Spk", NULL, "LHPOUT"},
{"Ext Spk", NULL, "RHPOUT"},
/* mic is connected to Mic Jack, with WM8731 Mic Bias */ /* mic is connected to Mic Jack, with WM8731 Mic Bias */
{"MICIN", NULL, "Mic Bias"}, {"MICIN", NULL, "Mic Bias"},
...@@ -108,9 +109,7 @@ static const struct snd_soc_dapm_route intercon[] = { ...@@ -108,9 +109,7 @@ static const struct snd_soc_dapm_route intercon[] = {
*/ */
static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{ {
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dapm_context *dapm = &codec->dapm;
int ret; int ret;
printk(KERN_DEBUG printk(KERN_DEBUG
...@@ -124,10 +123,6 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) ...@@ -124,10 +123,6 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
return ret; return ret;
} }
/* not connected */
snd_soc_dapm_nc_pin(dapm, "RLINEIN");
snd_soc_dapm_nc_pin(dapm, "LLINEIN");
#ifndef ENABLE_MIC_INPUT #ifndef ENABLE_MIC_INPUT
snd_soc_dapm_nc_pin(&rtd->card->dapm, "Int Mic"); snd_soc_dapm_nc_pin(&rtd->card->dapm, "Int Mic");
#endif #endif
...@@ -158,6 +153,7 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = { ...@@ -158,6 +153,7 @@ static struct snd_soc_card snd_soc_at91sam9g20ek = {
.num_dapm_widgets = ARRAY_SIZE(at91sam9g20ek_dapm_widgets), .num_dapm_widgets = ARRAY_SIZE(at91sam9g20ek_dapm_widgets),
.dapm_routes = intercon, .dapm_routes = intercon,
.num_dapm_routes = ARRAY_SIZE(intercon), .num_dapm_routes = ARRAY_SIZE(intercon),
.fully_routed = true,
}; };
static int at91sam9g20ek_audio_probe(struct platform_device *pdev) static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include "../codecs/wm8731.h" #include "../codecs/wm8731.h"
#include "psc.h" #include "psc.h"
static struct platform_device_id db1200_pids[] = { static const struct platform_device_id db1200_pids[] = {
{ {
.name = "db1200-ac97", .name = "db1200-ac97",
.driver_data = 0, .driver_data = 0,
......
...@@ -60,7 +60,6 @@ int devm_ep93xx_pcm_platform_register(struct device *dev) ...@@ -60,7 +60,6 @@ int devm_ep93xx_pcm_platform_register(struct device *dev)
{ {
return devm_snd_dmaengine_pcm_register(dev, return devm_snd_dmaengine_pcm_register(dev,
&ep93xx_dmaengine_pcm_config, &ep93xx_dmaengine_pcm_config,
SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
SND_DMAENGINE_PCM_FLAG_NO_DT | SND_DMAENGINE_PCM_FLAG_NO_DT |
SND_DMAENGINE_PCM_FLAG_COMPAT); SND_DMAENGINE_PCM_FLAG_COMPAT);
} }
......
...@@ -1140,7 +1140,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec, ...@@ -1140,7 +1140,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
/* Enable Audio PLL & Audio section */ /* Enable Audio PLL & Audio section */
data = AUDIO_PLL | AUDIO_SECTION_ON; data = AUDIO_PLL | AUDIO_SECTION_ON;
pm860x_reg_write(pm860x->i2c, REG_MISC2, data); pm860x_reg_write(pm860x->i2c, REG_MISC2, data);
...@@ -1156,7 +1156,6 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec, ...@@ -1156,7 +1156,6 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
pm860x_set_bits(pm860x->i2c, REG_MISC2, data, 0); pm860x_set_bits(pm860x->i2c, REG_MISC2, data, 0);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -16,7 +16,7 @@ config SND_SOC_ALL_CODECS ...@@ -16,7 +16,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_88PM860X if MFD_88PM860X select SND_SOC_88PM860X if MFD_88PM860X
select SND_SOC_L3 select SND_SOC_L3
select SND_SOC_AB8500_CODEC if ABX500_CORE select SND_SOC_AB8500_CODEC if ABX500_CORE
select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS select SND_SOC_AC97_CODEC
select SND_SOC_AD1836 if SPI_MASTER select SND_SOC_AD1836 if SPI_MASTER
select SND_SOC_AD193X_SPI if SPI_MASTER select SND_SOC_AD193X_SPI if SPI_MASTER
select SND_SOC_AD193X_I2C if I2C select SND_SOC_AD193X_I2C if I2C
...@@ -54,7 +54,7 @@ config SND_SOC_ALL_CODECS ...@@ -54,7 +54,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS4271_SPI if SPI_MASTER select SND_SOC_CS4271_SPI if SPI_MASTER
select SND_SOC_CS42XX8_I2C if I2C select SND_SOC_CS42XX8_I2C if I2C
select SND_SOC_CX20442 if TTY select SND_SOC_CX20442 if TTY
select SND_SOC_DA7210 if I2C select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
select SND_SOC_DA7213 if I2C select SND_SOC_DA7213 if I2C
select SND_SOC_DA732X if I2C select SND_SOC_DA732X if I2C
select SND_SOC_DA9055 if I2C select SND_SOC_DA9055 if I2C
...@@ -104,6 +104,7 @@ config SND_SOC_ALL_CODECS ...@@ -104,6 +104,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_STAC9766 if SND_SOC_AC97_BUS select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
select SND_SOC_TAS2552 if I2C select SND_SOC_TAS2552 if I2C
select SND_SOC_TAS5086 if I2C select SND_SOC_TAS5086 if I2C
select SND_SOC_TAS571X if I2C
select SND_SOC_TFA9879 if I2C select SND_SOC_TFA9879 if I2C
select SND_SOC_TLV320AIC23_I2C if I2C select SND_SOC_TLV320AIC23_I2C if I2C
select SND_SOC_TLV320AIC23_SPI if SPI_MASTER select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
...@@ -211,8 +212,9 @@ config SND_SOC_AB8500_CODEC ...@@ -211,8 +212,9 @@ config SND_SOC_AB8500_CODEC
tristate tristate
config SND_SOC_AC97_CODEC config SND_SOC_AC97_CODEC
tristate tristate "Build generic ASoC AC97 CODEC driver"
select SND_AC97_CODEC select SND_AC97_CODEC
select SND_SOC_AC97_BUS
config SND_SOC_AD1836 config SND_SOC_AD1836
tristate tristate
...@@ -611,6 +613,10 @@ config SND_SOC_TAS5086 ...@@ -611,6 +613,10 @@ config SND_SOC_TAS5086
tristate "Texas Instruments TAS5086 speaker amplifier" tristate "Texas Instruments TAS5086 speaker amplifier"
depends on I2C depends on I2C
config SND_SOC_TAS571X
tristate "Texas Instruments TAS5711/TAS5717/TAS5719 power amplifiers"
depends on I2C
config SND_SOC_TFA9879 config SND_SOC_TFA9879
tristate "NXP Semiconductors TFA9879 amplifier" tristate "NXP Semiconductors TFA9879 amplifier"
depends on I2C depends on I2C
......
...@@ -106,6 +106,7 @@ snd-soc-sta350-objs := sta350.o ...@@ -106,6 +106,7 @@ snd-soc-sta350-objs := sta350.o
snd-soc-sta529-objs := sta529.o snd-soc-sta529-objs := sta529.o
snd-soc-stac9766-objs := stac9766.o snd-soc-stac9766-objs := stac9766.o
snd-soc-tas5086-objs := tas5086.o snd-soc-tas5086-objs := tas5086.o
snd-soc-tas571x-objs := tas571x.o
snd-soc-tfa9879-objs := tfa9879.o snd-soc-tfa9879-objs := tfa9879.o
snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic23-objs := tlv320aic23.o
snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
...@@ -288,6 +289,7 @@ obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o ...@@ -288,6 +289,7 @@ obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o
obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o
obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o
obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
......
...@@ -1209,6 +1209,7 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol, ...@@ -1209,6 +1209,7 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
struct device *dev = codec->dev; struct device *dev = codec->dev;
bool apply_fir, apply_iir; bool apply_fir, apply_iir;
...@@ -1234,15 +1235,14 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol, ...@@ -1234,15 +1235,14 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol,
apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR; apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR;
apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR; apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR;
status = snd_soc_dapm_force_enable_pin(&codec->dapm, status = snd_soc_dapm_force_enable_pin(dapm, "ANC Configure Input");
"ANC Configure Input");
if (status < 0) { if (status < 0) {
dev_err(dev, dev_err(dev,
"%s: ERROR: Failed to enable power (status = %d)!\n", "%s: ERROR: Failed to enable power (status = %d)!\n",
__func__, status); __func__, status);
goto cleanup; goto cleanup;
} }
snd_soc_dapm_sync(&codec->dapm); snd_soc_dapm_sync(dapm);
anc_configure(codec, apply_fir, apply_iir); anc_configure(codec, apply_fir, apply_iir);
...@@ -1259,8 +1259,8 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol, ...@@ -1259,8 +1259,8 @@ static int anc_status_control_put(struct snd_kcontrol *kcontrol,
drvdata->anc_status = ANC_IIR_CONFIGURED; drvdata->anc_status = ANC_IIR_CONFIGURED;
} }
status = snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input"); status = snd_soc_dapm_disable_pin(dapm, "ANC Configure Input");
snd_soc_dapm_sync(&codec->dapm); snd_soc_dapm_sync(dapm);
cleanup: cleanup:
mutex_unlock(&drvdata->ctrl_lock); mutex_unlock(&drvdata->ctrl_lock);
...@@ -1947,6 +1947,7 @@ static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec) ...@@ -1947,6 +1947,7 @@ static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec)
static int ab8500_audio_setup_mics(struct snd_soc_codec *codec, static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
struct amic_settings *amics) struct amic_settings *amics)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
u8 value8; u8 value8;
unsigned int value; unsigned int value;
int status; int status;
...@@ -1973,15 +1974,15 @@ static int ab8500_audio_setup_mics(struct snd_soc_codec *codec, ...@@ -1973,15 +1974,15 @@ static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__, dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__,
amic_micbias_str(amics->mic1a_micbias)); amic_micbias_str(amics->mic1a_micbias));
route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias]; route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias];
status = snd_soc_dapm_add_routes(&codec->dapm, route, 1); status = snd_soc_dapm_add_routes(dapm, route, 1);
dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__, dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__,
amic_micbias_str(amics->mic1b_micbias)); amic_micbias_str(amics->mic1b_micbias));
route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias]; route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias];
status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1); status |= snd_soc_dapm_add_routes(dapm, route, 1);
dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__, dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__,
amic_micbias_str(amics->mic2_micbias)); amic_micbias_str(amics->mic2_micbias));
route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias]; route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias];
status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1); status |= snd_soc_dapm_add_routes(dapm, route, 1);
if (status < 0) { if (status < 0) {
dev_err(codec->dev, dev_err(codec->dev,
"%s: Failed to add AMic-regulator DAPM-routes (%d).\n", "%s: Failed to add AMic-regulator DAPM-routes (%d).\n",
...@@ -2461,6 +2462,7 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np, ...@@ -2461,6 +2462,7 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
static int ab8500_codec_probe(struct snd_soc_codec *codec) static int ab8500_codec_probe(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct device *dev = codec->dev; struct device *dev = codec->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
...@@ -2541,7 +2543,7 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) ...@@ -2541,7 +2543,7 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
&ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value; &ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value;
drvdata->sid_fir_values = (long *)fc->value; drvdata->sid_fir_values = (long *)fc->value;
(void)snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input"); snd_soc_dapm_disable_pin(dapm, "ANC Configure Input");
mutex_init(&drvdata->ctrl_lock); mutex_init(&drvdata->ctrl_lock);
......
...@@ -44,10 +44,6 @@ static int ac97_prepare(struct snd_pcm_substream *substream, ...@@ -44,10 +44,6 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
return snd_ac97_set_rate(ac97, reg, substream->runtime->rate); return snd_ac97_set_rate(ac97, reg, substream->runtime->rate);
} }
#define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\
SNDRV_PCM_RATE_48000)
static const struct snd_soc_dai_ops ac97_dai_ops = { static const struct snd_soc_dai_ops ac97_dai_ops = {
.prepare = ac97_prepare, .prepare = ac97_prepare,
}; };
...@@ -58,13 +54,13 @@ static struct snd_soc_dai_driver ac97_dai = { ...@@ -58,13 +54,13 @@ static struct snd_soc_dai_driver ac97_dai = {
.stream_name = "AC97 Playback", .stream_name = "AC97 Playback",
.channels_min = 1, .channels_min = 1,
.channels_max = 2, .channels_max = 2,
.rates = STD_AC97_RATES, .rates = SNDRV_PCM_RATE_KNOT,
.formats = SND_SOC_STD_AC97_FMTS,}, .formats = SND_SOC_STD_AC97_FMTS,},
.capture = { .capture = {
.stream_name = "AC97 Capture", .stream_name = "AC97 Capture",
.channels_min = 1, .channels_min = 1,
.channels_max = 2, .channels_max = 2,
.rates = STD_AC97_RATES, .rates = SNDRV_PCM_RATE_KNOT,
.formats = SND_SOC_STD_AC97_FMTS,}, .formats = SND_SOC_STD_AC97_FMTS,},
.ops = &ac97_dai_ops, .ops = &ac97_dai_ops,
}; };
......
...@@ -251,7 +251,7 @@ static int ad1836_resume(struct snd_soc_codec *codec) ...@@ -251,7 +251,7 @@ static int ad1836_resume(struct snd_soc_codec *codec)
static int ad1836_probe(struct snd_soc_codec *codec) static int ad1836_probe(struct snd_soc_codec *codec)
{ {
struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec); struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
int num_dacs, num_adcs; int num_dacs, num_adcs;
int ret = 0; int ret = 0;
int i; int i;
......
...@@ -1444,7 +1444,6 @@ static int adau1373_set_bias_level(struct snd_soc_codec *codec, ...@@ -1444,7 +1444,6 @@ static int adau1373_set_bias_level(struct snd_soc_codec *codec,
ADAU1373_PWDN_CTRL3_PWR_EN, 0); ADAU1373_PWDN_CTRL3_PWR_EN, 0);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/regulator/consumer.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
...@@ -101,6 +102,10 @@ ...@@ -101,6 +102,10 @@
#define ADAU1701_FIRMWARE "adau1701.bin" #define ADAU1701_FIRMWARE "adau1701.bin"
static const char * const supply_names[] = {
"dvdd", "avdd"
};
struct adau1701 { struct adau1701 {
int gpio_nreset; int gpio_nreset;
int gpio_pll_mode[2]; int gpio_pll_mode[2];
...@@ -112,6 +117,7 @@ struct adau1701 { ...@@ -112,6 +117,7 @@ struct adau1701 {
u8 pin_config[12]; u8 pin_config[12];
struct sigmadsp *sigmadsp; struct sigmadsp *sigmadsp;
struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
}; };
static const struct snd_kcontrol_new adau1701_controls[] = { static const struct snd_kcontrol_new adau1701_controls[] = {
...@@ -565,7 +571,6 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec, ...@@ -565,7 +571,6 @@ static int adau1701_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -669,6 +674,13 @@ static int adau1701_probe(struct snd_soc_codec *codec) ...@@ -669,6 +674,13 @@ static int adau1701_probe(struct snd_soc_codec *codec)
if (ret) if (ret)
return ret; return ret;
ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
adau1701->supplies);
if (ret < 0) {
dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
return ret;
}
/* /*
* Let the pll_clkdiv variable default to something that won't happen * Let the pll_clkdiv variable default to something that won't happen
* at runtime. That way, we can postpone the firmware download from * at runtime. That way, we can postpone the firmware download from
...@@ -680,7 +692,7 @@ static int adau1701_probe(struct snd_soc_codec *codec) ...@@ -680,7 +692,7 @@ static int adau1701_probe(struct snd_soc_codec *codec)
/* initalize with pre-configured pll mode settings */ /* initalize with pre-configured pll mode settings */
ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0); ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0);
if (ret < 0) if (ret < 0)
return ret; goto exit_regulators_disable;
/* set up pin config */ /* set up pin config */
val = 0; val = 0;
...@@ -696,10 +708,60 @@ static int adau1701_probe(struct snd_soc_codec *codec) ...@@ -696,10 +708,60 @@ static int adau1701_probe(struct snd_soc_codec *codec)
regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val); regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val);
return 0; return 0;
exit_regulators_disable:
regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
return ret;
} }
static int adau1701_remove(struct snd_soc_codec *codec)
{
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
if (gpio_is_valid(adau1701->gpio_nreset))
gpio_set_value_cansleep(adau1701->gpio_nreset, 0);
regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
return 0;
}
#ifdef CONFIG_PM
static int adau1701_suspend(struct snd_soc_codec *codec)
{
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies),
adau1701->supplies);
return 0;
}
static int adau1701_resume(struct snd_soc_codec *codec)
{
struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec);
int ret;
ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
adau1701->supplies);
if (ret < 0) {
dev_err(codec->dev, "Failed to enable regulators: %d\n", ret);
return ret;
}
return adau1701_reset(codec, adau1701->pll_clkdiv, 0);
}
#else
#define adau1701_resume NULL
#define adau1701_suspend NULL
#endif /* CONFIG_PM */
static struct snd_soc_codec_driver adau1701_codec_drv = { static struct snd_soc_codec_driver adau1701_codec_drv = {
.probe = adau1701_probe, .probe = adau1701_probe,
.remove = adau1701_remove,
.resume = adau1701_resume,
.suspend = adau1701_suspend,
.set_bias_level = adau1701_set_bias_level, .set_bias_level = adau1701_set_bias_level,
.idle_bias_off = true, .idle_bias_off = true,
...@@ -730,32 +792,58 @@ static int adau1701_i2c_probe(struct i2c_client *client, ...@@ -730,32 +792,58 @@ static int adau1701_i2c_probe(struct i2c_client *client,
struct device *dev = &client->dev; struct device *dev = &client->dev;
int gpio_nreset = -EINVAL; int gpio_nreset = -EINVAL;
int gpio_pll_mode[2] = { -EINVAL, -EINVAL }; int gpio_pll_mode[2] = { -EINVAL, -EINVAL };
int ret; int ret, i;
adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL); adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL);
if (!adau1701) if (!adau1701)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(supply_names); i++)
adau1701->supplies[i].supply = supply_names[i];
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(adau1701->supplies),
adau1701->supplies);
if (ret < 0) {
dev_err(dev, "Failed to get regulators: %d\n", ret);
return ret;
}
ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies),
adau1701->supplies);
if (ret < 0) {
dev_err(dev, "Failed to enable regulators: %d\n", ret);
return ret;
}
adau1701->client = client; adau1701->client = client;
adau1701->regmap = devm_regmap_init(dev, NULL, client, adau1701->regmap = devm_regmap_init(dev, NULL, client,
&adau1701_regmap); &adau1701_regmap);
if (IS_ERR(adau1701->regmap)) if (IS_ERR(adau1701->regmap)) {
return PTR_ERR(adau1701->regmap); ret = PTR_ERR(adau1701->regmap);
goto exit_regulators_disable;
}
if (dev->of_node) { if (dev->of_node) {
gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0); gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0);
if (gpio_nreset < 0 && gpio_nreset != -ENOENT) if (gpio_nreset < 0 && gpio_nreset != -ENOENT) {
return gpio_nreset; ret = gpio_nreset;
goto exit_regulators_disable;
}
gpio_pll_mode[0] = of_get_named_gpio(dev->of_node, gpio_pll_mode[0] = of_get_named_gpio(dev->of_node,
"adi,pll-mode-gpios", 0); "adi,pll-mode-gpios", 0);
if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT) if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT) {
return gpio_pll_mode[0]; ret = gpio_pll_mode[0];
goto exit_regulators_disable;
}
gpio_pll_mode[1] = of_get_named_gpio(dev->of_node, gpio_pll_mode[1] = of_get_named_gpio(dev->of_node,
"adi,pll-mode-gpios", 1); "adi,pll-mode-gpios", 1);
if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT) if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT) {
return gpio_pll_mode[1]; ret = gpio_pll_mode[1];
goto exit_regulators_disable;
}
of_property_read_u32(dev->of_node, "adi,pll-clkdiv", of_property_read_u32(dev->of_node, "adi,pll-clkdiv",
&adau1701->pll_clkdiv); &adau1701->pll_clkdiv);
...@@ -769,7 +857,7 @@ static int adau1701_i2c_probe(struct i2c_client *client, ...@@ -769,7 +857,7 @@ static int adau1701_i2c_probe(struct i2c_client *client,
ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW, ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW,
"ADAU1701 Reset"); "ADAU1701 Reset");
if (ret < 0) if (ret < 0)
return ret; goto exit_regulators_disable;
} }
if (gpio_is_valid(gpio_pll_mode[0]) && if (gpio_is_valid(gpio_pll_mode[0]) &&
...@@ -778,13 +866,13 @@ static int adau1701_i2c_probe(struct i2c_client *client, ...@@ -778,13 +866,13 @@ static int adau1701_i2c_probe(struct i2c_client *client,
GPIOF_OUT_INIT_LOW, GPIOF_OUT_INIT_LOW,
"ADAU1701 PLL mode 0"); "ADAU1701 PLL mode 0");
if (ret < 0) if (ret < 0)
return ret; goto exit_regulators_disable;
ret = devm_gpio_request_one(dev, gpio_pll_mode[1], ret = devm_gpio_request_one(dev, gpio_pll_mode[1],
GPIOF_OUT_INIT_LOW, GPIOF_OUT_INIT_LOW,
"ADAU1701 PLL mode 1"); "ADAU1701 PLL mode 1");
if (ret < 0) if (ret < 0)
return ret; goto exit_regulators_disable;
} }
adau1701->gpio_nreset = gpio_nreset; adau1701->gpio_nreset = gpio_nreset;
...@@ -795,11 +883,17 @@ static int adau1701_i2c_probe(struct i2c_client *client, ...@@ -795,11 +883,17 @@ static int adau1701_i2c_probe(struct i2c_client *client,
adau1701->sigmadsp = devm_sigmadsp_init_i2c(client, adau1701->sigmadsp = devm_sigmadsp_init_i2c(client,
&adau1701_sigmadsp_ops, ADAU1701_FIRMWARE); &adau1701_sigmadsp_ops, ADAU1701_FIRMWARE);
if (IS_ERR(adau1701->sigmadsp)) if (IS_ERR(adau1701->sigmadsp)) {
return PTR_ERR(adau1701->sigmadsp); ret = PTR_ERR(adau1701->sigmadsp);
goto exit_regulators_disable;
}
ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv,
&adau1701_dai, 1); &adau1701_dai, 1);
exit_regulators_disable:
regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies);
return ret; return ret;
} }
......
...@@ -466,7 +466,6 @@ static int adau1761_set_bias_level(struct snd_soc_codec *codec, ...@@ -466,7 +466,6 @@ static int adau1761_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -483,6 +482,7 @@ static enum adau1761_output_mode adau1761_get_lineout_mode( ...@@ -483,6 +482,7 @@ static enum adau1761_output_mode adau1761_get_lineout_mode(
static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec) static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adau1761_platform_data *pdata = codec->dev->platform_data; struct adau1761_platform_data *pdata = codec->dev->platform_data;
struct adau *adau = snd_soc_codec_get_drvdata(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec);
enum adau1761_digmic_jackdet_pin_mode mode; enum adau1761_digmic_jackdet_pin_mode mode;
...@@ -515,21 +515,18 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec) ...@@ -515,21 +515,18 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
if (ret) if (ret)
return ret; return ret;
case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: /* fallthrough */ case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: /* fallthrough */
ret = snd_soc_dapm_add_routes(&codec->dapm, ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes,
adau1761_no_dmic_routes,
ARRAY_SIZE(adau1761_no_dmic_routes)); ARRAY_SIZE(adau1761_no_dmic_routes));
if (ret) if (ret)
return ret; return ret;
break; break;
case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC: case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC:
ret = snd_soc_dapm_new_controls(&codec->dapm, ret = snd_soc_dapm_new_controls(dapm, adau1761_dmic_widgets,
adau1761_dmic_widgets,
ARRAY_SIZE(adau1761_dmic_widgets)); ARRAY_SIZE(adau1761_dmic_widgets));
if (ret) if (ret)
return ret; return ret;
ret = snd_soc_dapm_add_routes(&codec->dapm, ret = snd_soc_dapm_add_routes(dapm, adau1761_dmic_routes,
adau1761_dmic_routes,
ARRAY_SIZE(adau1761_dmic_routes)); ARRAY_SIZE(adau1761_dmic_routes));
if (ret) if (ret)
return ret; return ret;
...@@ -547,6 +544,7 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec) ...@@ -547,6 +544,7 @@ static int adau1761_setup_digmic_jackdetect(struct snd_soc_codec *codec)
static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec) static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adau *adau = snd_soc_codec_get_drvdata(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec);
struct adau1761_platform_data *pdata = codec->dev->platform_data; struct adau1761_platform_data *pdata = codec->dev->platform_data;
enum adau1761_output_mode mode; enum adau1761_output_mode mode;
...@@ -577,12 +575,12 @@ static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec) ...@@ -577,12 +575,12 @@ static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
} }
if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) { if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) {
ret = snd_soc_dapm_new_controls(&codec->dapm, ret = snd_soc_dapm_new_controls(dapm,
adau1761_capless_dapm_widgets, adau1761_capless_dapm_widgets,
ARRAY_SIZE(adau1761_capless_dapm_widgets)); ARRAY_SIZE(adau1761_capless_dapm_widgets));
if (ret) if (ret)
return ret; return ret;
ret = snd_soc_dapm_add_routes(&codec->dapm, ret = snd_soc_dapm_add_routes(dapm,
adau1761_capless_dapm_routes, adau1761_capless_dapm_routes,
ARRAY_SIZE(adau1761_capless_dapm_routes)); ARRAY_SIZE(adau1761_capless_dapm_routes));
} else { } else {
...@@ -590,12 +588,12 @@ static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec) ...@@ -590,12 +588,12 @@ static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
ARRAY_SIZE(adau1761_mono_controls)); ARRAY_SIZE(adau1761_mono_controls));
if (ret) if (ret)
return ret; return ret;
ret = snd_soc_dapm_new_controls(&codec->dapm, ret = snd_soc_dapm_new_controls(dapm,
adau1761_mono_dapm_widgets, adau1761_mono_dapm_widgets,
ARRAY_SIZE(adau1761_mono_dapm_widgets)); ARRAY_SIZE(adau1761_mono_dapm_widgets));
if (ret) if (ret)
return ret; return ret;
ret = snd_soc_dapm_add_routes(&codec->dapm, ret = snd_soc_dapm_add_routes(dapm,
adau1761_mono_dapm_routes, adau1761_mono_dapm_routes,
ARRAY_SIZE(adau1761_mono_dapm_routes)); ARRAY_SIZE(adau1761_mono_dapm_routes));
} }
...@@ -640,6 +638,7 @@ static bool adau1761_readable_register(struct device *dev, unsigned int reg) ...@@ -640,6 +638,7 @@ static bool adau1761_readable_register(struct device *dev, unsigned int reg)
static int adau1761_codec_probe(struct snd_soc_codec *codec) static int adau1761_codec_probe(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adau1761_platform_data *pdata = codec->dev->platform_data; struct adau1761_platform_data *pdata = codec->dev->platform_data;
struct adau *adau = snd_soc_codec_get_drvdata(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec);
int ret; int ret;
...@@ -692,14 +691,12 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec) ...@@ -692,14 +691,12 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
return ret; return ret;
if (adau->type == ADAU1761) { if (adau->type == ADAU1761) {
ret = snd_soc_dapm_new_controls(&codec->dapm, ret = snd_soc_dapm_new_controls(dapm, adau1761_dapm_widgets,
adau1761_dapm_widgets,
ARRAY_SIZE(adau1761_dapm_widgets)); ARRAY_SIZE(adau1761_dapm_widgets));
if (ret) if (ret)
return ret; return ret;
ret = snd_soc_dapm_add_routes(&codec->dapm, ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_routes,
adau1761_dapm_routes,
ARRAY_SIZE(adau1761_dapm_routes)); ARRAY_SIZE(adau1761_dapm_routes));
if (ret) if (ret)
return ret; return ret;
......
...@@ -339,7 +339,6 @@ static int adau1781_set_bias_level(struct snd_soc_codec *codec, ...@@ -339,7 +339,6 @@ static int adau1781_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -383,6 +382,7 @@ static int adau1781_set_input_mode(struct adau *adau, unsigned int reg, ...@@ -383,6 +382,7 @@ static int adau1781_set_input_mode(struct adau *adau, unsigned int reg,
static int adau1781_codec_probe(struct snd_soc_codec *codec) static int adau1781_codec_probe(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adau1781_platform_data *pdata = dev_get_platdata(codec->dev); struct adau1781_platform_data *pdata = dev_get_platdata(codec->dev);
struct adau *adau = snd_soc_codec_get_drvdata(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec);
int ret; int ret;
...@@ -403,19 +403,17 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec) ...@@ -403,19 +403,17 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec)
} }
if (pdata && pdata->use_dmic) { if (pdata && pdata->use_dmic) {
ret = snd_soc_dapm_new_controls(&codec->dapm, ret = snd_soc_dapm_new_controls(dapm,
adau1781_dmic_dapm_widgets, adau1781_dmic_dapm_widgets,
ARRAY_SIZE(adau1781_dmic_dapm_widgets)); ARRAY_SIZE(adau1781_dmic_dapm_widgets));
if (ret) if (ret)
return ret; return ret;
ret = snd_soc_dapm_add_routes(&codec->dapm, ret = snd_soc_dapm_add_routes(dapm, adau1781_dmic_dapm_routes,
adau1781_dmic_dapm_routes,
ARRAY_SIZE(adau1781_dmic_dapm_routes)); ARRAY_SIZE(adau1781_dmic_dapm_routes));
if (ret) if (ret)
return ret; return ret;
} else { } else {
ret = snd_soc_dapm_add_routes(&codec->dapm, ret = snd_soc_dapm_add_routes(dapm, adau1781_adc_dapm_routes,
adau1781_adc_dapm_routes,
ARRAY_SIZE(adau1781_adc_dapm_routes)); ARRAY_SIZE(adau1781_adc_dapm_routes));
if (ret) if (ret)
return ret; return ret;
......
...@@ -155,6 +155,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol, ...@@ -155,6 +155,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adau *adau = snd_soc_codec_get_drvdata(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
struct snd_soc_dapm_update update; struct snd_soc_dapm_update update;
...@@ -188,7 +189,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol, ...@@ -188,7 +189,7 @@ static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
update.reg = reg; update.reg = reg;
update.val = val; update.val = val;
snd_soc_dapm_mux_update_power(&codec->dapm, kcontrol, snd_soc_dapm_mux_update_power(dapm, kcontrol,
ucontrol->value.enumerated.item[0], e, &update); ucontrol->value.enumerated.item[0], e, &update);
} }
...@@ -444,8 +445,8 @@ static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id, ...@@ -444,8 +445,8 @@ static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai, static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir) int clk_id, unsigned int freq, int dir)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(dai->codec);
struct adau *adau = snd_soc_codec_get_drvdata(dai->codec); struct adau *adau = snd_soc_codec_get_drvdata(dai->codec);
struct snd_soc_dapm_context *dapm = &dai->codec->dapm;
switch (clk_id) { switch (clk_id) {
case ADAU17X1_CLK_SRC_MCLK: case ADAU17X1_CLK_SRC_MCLK:
...@@ -804,6 +805,7 @@ EXPORT_SYMBOL_GPL(adau17x1_setup_firmware); ...@@ -804,6 +805,7 @@ EXPORT_SYMBOL_GPL(adau17x1_setup_firmware);
int adau17x1_add_widgets(struct snd_soc_codec *codec) int adau17x1_add_widgets(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adau *adau = snd_soc_codec_get_drvdata(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec);
int ret; int ret;
...@@ -811,14 +813,13 @@ int adau17x1_add_widgets(struct snd_soc_codec *codec) ...@@ -811,14 +813,13 @@ int adau17x1_add_widgets(struct snd_soc_codec *codec)
ARRAY_SIZE(adau17x1_controls)); ARRAY_SIZE(adau17x1_controls));
if (ret) if (ret)
return ret; return ret;
ret = snd_soc_dapm_new_controls(&codec->dapm, adau17x1_dapm_widgets, ret = snd_soc_dapm_new_controls(dapm, adau17x1_dapm_widgets,
ARRAY_SIZE(adau17x1_dapm_widgets)); ARRAY_SIZE(adau17x1_dapm_widgets));
if (ret) if (ret)
return ret; return ret;
if (adau17x1_has_dsp(adau)) { if (adau17x1_has_dsp(adau)) {
ret = snd_soc_dapm_new_controls(&codec->dapm, ret = snd_soc_dapm_new_controls(dapm, adau17x1_dsp_dapm_widgets,
adau17x1_dsp_dapm_widgets,
ARRAY_SIZE(adau17x1_dsp_dapm_widgets)); ARRAY_SIZE(adau17x1_dsp_dapm_widgets));
if (ret) if (ret)
return ret; return ret;
...@@ -840,21 +841,20 @@ EXPORT_SYMBOL_GPL(adau17x1_add_widgets); ...@@ -840,21 +841,20 @@ EXPORT_SYMBOL_GPL(adau17x1_add_widgets);
int adau17x1_add_routes(struct snd_soc_codec *codec) int adau17x1_add_routes(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adau *adau = snd_soc_codec_get_drvdata(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec);
int ret; int ret;
ret = snd_soc_dapm_add_routes(&codec->dapm, adau17x1_dapm_routes, ret = snd_soc_dapm_add_routes(dapm, adau17x1_dapm_routes,
ARRAY_SIZE(adau17x1_dapm_routes)); ARRAY_SIZE(adau17x1_dapm_routes));
if (ret) if (ret)
return ret; return ret;
if (adau17x1_has_dsp(adau)) { if (adau17x1_has_dsp(adau)) {
ret = snd_soc_dapm_add_routes(&codec->dapm, ret = snd_soc_dapm_add_routes(dapm, adau17x1_dsp_dapm_routes,
adau17x1_dsp_dapm_routes,
ARRAY_SIZE(adau17x1_dsp_dapm_routes)); ARRAY_SIZE(adau17x1_dsp_dapm_routes));
} else { } else {
ret = snd_soc_dapm_add_routes(&codec->dapm, ret = snd_soc_dapm_add_routes(dapm, adau17x1_no_dsp_dapm_routes,
adau17x1_no_dsp_dapm_routes,
ARRAY_SIZE(adau17x1_no_dsp_dapm_routes)); ARRAY_SIZE(adau17x1_no_dsp_dapm_routes));
} }
return ret; return ret;
......
...@@ -202,7 +202,7 @@ static const struct snd_soc_dapm_route adau1977_dapm_routes[] = { ...@@ -202,7 +202,7 @@ static const struct snd_soc_dapm_route adau1977_dapm_routes[] = {
ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0) ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0)
#define ADAU1977_DC_SUB_SWITCH(x) \ #define ADAU1977_DC_SUB_SWITCH(x) \
SOC_SINGLE("ADC" #x " DC Substraction Capture Switch", \ SOC_SINGLE("ADC" #x " DC Subtraction Capture Switch", \
ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0) ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0)
static const struct snd_kcontrol_new adau1977_snd_controls[] = { static const struct snd_kcontrol_new adau1977_snd_controls[] = {
...@@ -485,7 +485,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec, ...@@ -485,7 +485,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
ret = adau1977_power_enable(adau1977); ret = adau1977_power_enable(adau1977);
break; break;
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
...@@ -493,12 +493,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec, ...@@ -493,12 +493,7 @@ static int adau1977_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
if (ret) return ret;
return ret;
codec->dapm.bias_level = level;
return 0;
} }
static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
...@@ -853,12 +848,13 @@ static int adau1977_set_sysclk(struct snd_soc_codec *codec, ...@@ -853,12 +848,13 @@ static int adau1977_set_sysclk(struct snd_soc_codec *codec,
static int adau1977_codec_probe(struct snd_soc_codec *codec) static int adau1977_codec_probe(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec); struct adau1977 *adau1977 = snd_soc_codec_get_drvdata(codec);
int ret; int ret;
switch (adau1977->type) { switch (adau1977->type) {
case ADAU1977: case ADAU1977:
ret = snd_soc_dapm_new_controls(&codec->dapm, ret = snd_soc_dapm_new_controls(dapm,
adau1977_micbias_dapm_widgets, adau1977_micbias_dapm_widgets,
ARRAY_SIZE(adau1977_micbias_dapm_widgets)); ARRAY_SIZE(adau1977_micbias_dapm_widgets));
if (ret < 0) if (ret < 0)
......
...@@ -539,7 +539,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, ...@@ -539,7 +539,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
unsigned int freq, int dir) unsigned int freq, int dir)
{ {
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
if (dir == SND_SOC_CLOCK_IN) { if (dir == SND_SOC_CLOCK_IN) {
switch (clk_id) { switch (clk_id) {
...@@ -622,6 +622,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec, ...@@ -622,6 +622,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id, static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
int source, unsigned int freq_in, unsigned int freq_out) int source, unsigned int freq_in, unsigned int freq_out)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
unsigned int pll_ctrl1 = 0; unsigned int pll_ctrl1 = 0;
unsigned int pll_ctrl2 = 0; unsigned int pll_ctrl2 = 0;
...@@ -687,7 +688,7 @@ static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id, ...@@ -687,7 +688,7 @@ static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
adav80x->pll_src = source; adav80x->pll_src = source;
snd_soc_dapm_sync(&codec->dapm); snd_soc_dapm_sync(dapm);
} }
return 0; return 0;
...@@ -714,7 +715,6 @@ static int adav80x_set_bias_level(struct snd_soc_codec *codec, ...@@ -714,7 +715,6 @@ static int adav80x_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -801,11 +801,12 @@ static struct snd_soc_dai_driver adav80x_dais[] = { ...@@ -801,11 +801,12 @@ static struct snd_soc_dai_driver adav80x_dais[] = {
static int adav80x_probe(struct snd_soc_codec *codec) static int adav80x_probe(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
/* Force PLLs on for SYSCLK output */ /* Force PLLs on for SYSCLK output */
snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); snd_soc_dapm_force_enable_pin(dapm, "PLL1");
snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); snd_soc_dapm_force_enable_pin(dapm, "PLL2");
/* Power down S/PDIF receiver, since it is currently not supported */ /* Power down S/PDIF receiver, since it is currently not supported */
regmap_write(adav80x->regmap, ADAV80X_PLL_OUTE, 0x20); regmap_write(adav80x->regmap, ADAV80X_PLL_OUTE, 0x20);
......
...@@ -341,7 +341,6 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec, ...@@ -341,7 +341,6 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0); snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -412,7 +412,7 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec, ...@@ -412,7 +412,7 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20); snd_soc_update_bits(codec, AK4641_DAC, 0x20, 0x20);
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
if (pdata && gpio_is_valid(pdata->gpio_power)) if (pdata && gpio_is_valid(pdata->gpio_power))
gpio_set_value(pdata->gpio_power, 1); gpio_set_value(pdata->gpio_power, 1);
mdelay(1); mdelay(1);
...@@ -439,7 +439,6 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec, ...@@ -439,7 +439,6 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec,
regcache_mark_dirty(ak4641->regmap); regcache_mark_dirty(ak4641->regmap);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -482,7 +482,6 @@ static int ak4642_set_bias_level(struct snd_soc_codec *codec, ...@@ -482,7 +482,6 @@ static int ak4642_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM); snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -577,7 +577,6 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec, ...@@ -577,7 +577,6 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00); snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -826,7 +826,6 @@ static int alc5623_set_bias_level(struct snd_soc_codec *codec, ...@@ -826,7 +826,6 @@ static int alc5623_set_bias_level(struct snd_soc_codec *codec,
snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0); snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -894,7 +893,7 @@ static int alc5623_resume(struct snd_soc_codec *codec) ...@@ -894,7 +893,7 @@ static int alc5623_resume(struct snd_soc_codec *codec)
static int alc5623_probe(struct snd_soc_codec *codec) static int alc5623_probe(struct snd_soc_codec *codec)
{ {
struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
alc5623_reset(codec); alc5623_reset(codec);
......
...@@ -1000,7 +1000,6 @@ static int alc5632_set_bias_level(struct snd_soc_codec *codec, ...@@ -1000,7 +1000,6 @@ static int alc5632_set_bias_level(struct snd_soc_codec *codec,
ALC5632_PWR_MANAG_ADD1_MASK, 0); ALC5632_PWR_MANAG_ADD1_MASK, 0);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -208,11 +208,12 @@ static const struct snd_soc_dapm_widget arizona_spkr = ...@@ -208,11 +208,12 @@ static const struct snd_soc_dapm_widget arizona_spkr =
int arizona_init_spk(struct snd_soc_codec *codec) int arizona_init_spk(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona; struct arizona *arizona = priv->arizona;
int ret; int ret;
ret = snd_soc_dapm_new_controls(&codec->dapm, &arizona_spkl, 1); ret = snd_soc_dapm_new_controls(dapm, &arizona_spkl, 1);
if (ret != 0) if (ret != 0)
return ret; return ret;
...@@ -220,8 +221,7 @@ int arizona_init_spk(struct snd_soc_codec *codec) ...@@ -220,8 +221,7 @@ int arizona_init_spk(struct snd_soc_codec *codec)
case WM8997: case WM8997:
break; break;
default: default:
ret = snd_soc_dapm_new_controls(&codec->dapm, ret = snd_soc_dapm_new_controls(dapm, &arizona_spkr, 1);
&arizona_spkr, 1);
if (ret != 0) if (ret != 0)
return ret; return ret;
break; break;
...@@ -258,13 +258,14 @@ static const struct snd_soc_dapm_route arizona_mono_routes[] = { ...@@ -258,13 +258,14 @@ static const struct snd_soc_dapm_route arizona_mono_routes[] = {
int arizona_init_mono(struct snd_soc_codec *codec) int arizona_init_mono(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona; struct arizona *arizona = priv->arizona;
int i; int i;
for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) { for (i = 0; i < ARIZONA_MAX_OUTPUT; ++i) {
if (arizona->pdata.out_mono[i]) if (arizona->pdata.out_mono[i])
snd_soc_dapm_add_routes(&codec->dapm, snd_soc_dapm_add_routes(dapm,
&arizona_mono_routes[i], 1); &arizona_mono_routes[i], 1);
} }
...@@ -274,6 +275,7 @@ EXPORT_SYMBOL_GPL(arizona_init_mono); ...@@ -274,6 +275,7 @@ EXPORT_SYMBOL_GPL(arizona_init_mono);
int arizona_init_gpio(struct snd_soc_codec *codec) int arizona_init_gpio(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona; struct arizona *arizona = priv->arizona;
int i; int i;
...@@ -281,23 +283,21 @@ int arizona_init_gpio(struct snd_soc_codec *codec) ...@@ -281,23 +283,21 @@ int arizona_init_gpio(struct snd_soc_codec *codec)
switch (arizona->type) { switch (arizona->type) {
case WM5110: case WM5110:
case WM8280: case WM8280:
snd_soc_dapm_disable_pin(&codec->dapm, "DRC2 Signal Activity"); snd_soc_dapm_disable_pin(dapm, "DRC2 Signal Activity");
break; break;
default: default:
break; break;
} }
snd_soc_dapm_disable_pin(&codec->dapm, "DRC1 Signal Activity"); snd_soc_dapm_disable_pin(dapm, "DRC1 Signal Activity");
for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) { for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) { switch (arizona->pdata.gpio_defaults[i] & ARIZONA_GPN_FN_MASK) {
case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT: case ARIZONA_GP_FN_DRC1_SIGNAL_DETECT:
snd_soc_dapm_enable_pin(&codec->dapm, snd_soc_dapm_enable_pin(dapm, "DRC1 Signal Activity");
"DRC1 Signal Activity");
break; break;
case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT: case ARIZONA_GP_FN_DRC2_SIGNAL_DETECT:
snd_soc_dapm_enable_pin(&codec->dapm, snd_soc_dapm_enable_pin(dapm, "DRC2 Signal Activity");
"DRC2 Signal Activity");
break; break;
default: default:
break; break;
...@@ -851,6 +851,134 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w, ...@@ -851,6 +851,134 @@ int arizona_hp_ev(struct snd_soc_dapm_widget *w,
} }
EXPORT_SYMBOL_GPL(arizona_hp_ev); EXPORT_SYMBOL_GPL(arizona_hp_ev);
static int arizona_dvfs_enable(struct snd_soc_codec *codec)
{
const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona;
int ret;
ret = regulator_set_voltage(arizona->dcvdd, 1800000, 1800000);
if (ret) {
dev_err(codec->dev, "Failed to boost DCVDD: %d\n", ret);
return ret;
}
ret = regmap_update_bits(arizona->regmap,
ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
ARIZONA_SUBSYS_MAX_FREQ,
ARIZONA_SUBSYS_MAX_FREQ);
if (ret) {
dev_err(codec->dev, "Failed to enable subsys max: %d\n", ret);
regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
return ret;
}
return 0;
}
static int arizona_dvfs_disable(struct snd_soc_codec *codec)
{
const struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona *arizona = priv->arizona;
int ret;
ret = regmap_update_bits(arizona->regmap,
ARIZONA_DYNAMIC_FREQUENCY_SCALING_1,
ARIZONA_SUBSYS_MAX_FREQ, 0);
if (ret) {
dev_err(codec->dev, "Failed to disable subsys max: %d\n", ret);
return ret;
}
ret = regulator_set_voltage(arizona->dcvdd, 1200000, 1800000);
if (ret) {
dev_err(codec->dev, "Failed to unboost DCVDD: %d\n", ret);
return ret;
}
return 0;
}
int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags)
{
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
int ret = 0;
mutex_lock(&priv->dvfs_lock);
if (!priv->dvfs_cached && !priv->dvfs_reqs) {
ret = arizona_dvfs_enable(codec);
if (ret)
goto err;
}
priv->dvfs_reqs |= flags;
err:
mutex_unlock(&priv->dvfs_lock);
return ret;
}
EXPORT_SYMBOL_GPL(arizona_dvfs_up);
int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags)
{
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
unsigned int old_reqs;
int ret = 0;
mutex_lock(&priv->dvfs_lock);
old_reqs = priv->dvfs_reqs;
priv->dvfs_reqs &= ~flags;
if (!priv->dvfs_cached && old_reqs && !priv->dvfs_reqs)
ret = arizona_dvfs_disable(codec);
mutex_unlock(&priv->dvfs_lock);
return ret;
}
EXPORT_SYMBOL_GPL(arizona_dvfs_down);
int arizona_dvfs_sysclk_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);
int ret = 0;
mutex_lock(&priv->dvfs_lock);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
if (priv->dvfs_reqs)
ret = arizona_dvfs_enable(codec);
priv->dvfs_cached = false;
break;
case SND_SOC_DAPM_PRE_PMD:
/* We must ensure DVFS is disabled before the codec goes into
* suspend so that we are never in an illegal state of DVFS
* enabled without enough DCVDD
*/
priv->dvfs_cached = true;
if (priv->dvfs_reqs)
ret = arizona_dvfs_disable(codec);
break;
default:
break;
}
mutex_unlock(&priv->dvfs_lock);
return ret;
}
EXPORT_SYMBOL_GPL(arizona_dvfs_sysclk_ev);
void arizona_init_dvfs(struct arizona_priv *priv)
{
mutex_init(&priv->dvfs_lock);
}
EXPORT_SYMBOL_GPL(arizona_init_dvfs);
static unsigned int arizona_sysclk_48k_rates[] = { static unsigned int arizona_sysclk_48k_rates[] = {
6144000, 6144000,
12288000, 12288000,
...@@ -1266,7 +1394,7 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream, ...@@ -1266,7 +1394,7 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
int base = dai->driver->base; int base = dai->driver->base;
int i, sr_val; int i, sr_val, ret;
/* /*
* We will need to be more flexible than this in future, * We will need to be more flexible than this in future,
...@@ -1282,6 +1410,23 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream, ...@@ -1282,6 +1410,23 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,
} }
sr_val = i; sr_val = i;
switch (priv->arizona->type) {
case WM5102:
case WM8997:
if (arizona_sr_vals[sr_val] >= 88200)
ret = arizona_dvfs_up(codec, ARIZONA_DVFS_SR1_RQ);
else
ret = arizona_dvfs_down(codec, ARIZONA_DVFS_SR1_RQ);
if (ret) {
arizona_aif_err(dai, "Failed to change DVFS %d\n", ret);
return ret;
}
break;
default:
break;
}
switch (dai_priv->clk) { switch (dai_priv->clk) {
case ARIZONA_CLK_SYSCLK: case ARIZONA_CLK_SYSCLK:
switch (priv->arizona->type) { switch (priv->arizona->type) {
...@@ -1474,6 +1619,7 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, ...@@ -1474,6 +1619,7 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
int clk_id, unsigned int freq, int dir) int clk_id, unsigned int freq, int dir)
{ {
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec); struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1]; struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
struct snd_soc_dapm_route routes[2]; struct snd_soc_dapm_route routes[2];
...@@ -1504,15 +1650,15 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai, ...@@ -1504,15 +1650,15 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
routes[0].source = arizona_dai_clk_str(dai_priv->clk); routes[0].source = arizona_dai_clk_str(dai_priv->clk);
routes[1].source = arizona_dai_clk_str(dai_priv->clk); routes[1].source = arizona_dai_clk_str(dai_priv->clk);
snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));
routes[0].source = arizona_dai_clk_str(clk_id); routes[0].source = arizona_dai_clk_str(clk_id);
routes[1].source = arizona_dai_clk_str(clk_id); routes[1].source = arizona_dai_clk_str(clk_id);
snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes)); snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
dai_priv->clk = clk_id; dai_priv->clk = clk_id;
return snd_soc_dapm_sync(&codec->dapm); return snd_soc_dapm_sync(dapm);
} }
static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate) static int arizona_set_tristate(struct snd_soc_dai *dai, int tristate)
......
...@@ -60,6 +60,9 @@ ...@@ -60,6 +60,9 @@
#define ARIZONA_MAX_DAI 6 #define ARIZONA_MAX_DAI 6
#define ARIZONA_MAX_ADSP 4 #define ARIZONA_MAX_ADSP 4
#define ARIZONA_DVFS_SR1_RQ 0x001
#define ARIZONA_DVFS_ADSP1_RQ 0x100
struct arizona; struct arizona;
struct wm_adsp; struct wm_adsp;
...@@ -84,6 +87,10 @@ struct arizona_priv { ...@@ -84,6 +87,10 @@ struct arizona_priv {
unsigned int spk_ena:2; unsigned int spk_ena:2;
unsigned int spk_ena_pending:1; unsigned int spk_ena_pending:1;
unsigned int dvfs_reqs;
struct mutex dvfs_lock;
bool dvfs_cached;
}; };
#define ARIZONA_NUM_MIXER_INPUTS 103 #define ARIZONA_NUM_MIXER_INPUTS 103
...@@ -107,8 +114,8 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ...@@ -107,8 +114,8 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
arizona_mixer_tlv) arizona_mixer_tlv)
#define ARIZONA_MUX_ENUM_DECL(name, reg) \ #define ARIZONA_MUX_ENUM_DECL(name, reg) \
SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \ SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \
arizona_mixer_texts, arizona_mixer_values) name, reg, 0, 0xff, arizona_mixer_texts, arizona_mixer_values)
#define ARIZONA_MUX_CTL_DECL(name) \ #define ARIZONA_MUX_CTL_DECL(name) \
const struct snd_kcontrol_new name##_mux = \ const struct snd_kcontrol_new name##_mux = \
...@@ -245,6 +252,12 @@ struct arizona_fll { ...@@ -245,6 +252,12 @@ struct arizona_fll {
char clock_ok_name[ARIZONA_FLL_NAME_LEN]; char clock_ok_name[ARIZONA_FLL_NAME_LEN];
}; };
extern int arizona_dvfs_up(struct snd_soc_codec *codec, unsigned int flags);
extern int arizona_dvfs_down(struct snd_soc_codec *codec, unsigned int flags);
extern int arizona_dvfs_sysclk_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
extern void arizona_init_dvfs(struct arizona_priv *priv);
extern int arizona_init_fll(struct arizona *arizona, int id, int base, extern int arizona_init_fll(struct arizona *arizona, int id, int base,
int lock_irq, int ok_irq, struct arizona_fll *fll); int lock_irq, int ok_irq, struct arizona_fll *fll);
extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source, extern int arizona_set_fll_refclk(struct arizona_fll *fll, int source,
......
...@@ -63,7 +63,7 @@ static int bt_sco_remove(struct platform_device *pdev) ...@@ -63,7 +63,7 @@ static int bt_sco_remove(struct platform_device *pdev)
return 0; return 0;
} }
static struct platform_device_id bt_sco_driver_ids[] = { static const struct platform_device_id bt_sco_driver_ids[] = {
{ {
.name = "dfbmcs320", .name = "dfbmcs320",
}, },
...@@ -74,9 +74,18 @@ static struct platform_device_id bt_sco_driver_ids[] = { ...@@ -74,9 +74,18 @@ static struct platform_device_id bt_sco_driver_ids[] = {
}; };
MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids); MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids);
#if defined(CONFIG_OF)
static const struct of_device_id bt_sco_codec_of_match[] = {
{ .compatible = "delta,dfbmcs320", },
{},
};
MODULE_DEVICE_TABLE(of, bt_sco_codec_of_match);
#endif
static struct platform_driver bt_sco_driver = { static struct platform_driver bt_sco_driver = {
.driver = { .driver = {
.name = "bt-sco", .name = "bt-sco",
.of_match_table = of_match_ptr(bt_sco_codec_of_match),
}, },
.probe = bt_sco_probe, .probe = bt_sco_probe,
.remove = bt_sco_remove, .remove = bt_sco_remove,
......
...@@ -92,7 +92,6 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec, ...@@ -92,7 +92,6 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
DAVINCI_VC_REG12_POWER_ALL_OFF); DAVINCI_VC_REG12_POWER_ALL_OFF);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/version.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
......
...@@ -503,7 +503,6 @@ static int cs4265_set_bias_level(struct snd_soc_codec *codec, ...@@ -503,7 +503,6 @@ static int cs4265_set_bias_level(struct snd_soc_codec *codec,
CS4265_PWRCTL_PDN); CS4265_PWRCTL_PDN);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -897,7 +897,7 @@ static int cs42l52_set_bias_level(struct snd_soc_codec *codec, ...@@ -897,7 +897,7 @@ static int cs42l52_set_bias_level(struct snd_soc_codec *codec,
CS42L52_PWRCTL1_PDN_CODEC, 0); CS42L52_PWRCTL1_PDN_CODEC, 0);
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
regcache_cache_only(cs42l52->regmap, false); regcache_cache_only(cs42l52->regmap, false);
regcache_sync(cs42l52->regmap); regcache_sync(cs42l52->regmap);
} }
...@@ -908,7 +908,6 @@ static int cs42l52_set_bias_level(struct snd_soc_codec *codec, ...@@ -908,7 +908,6 @@ static int cs42l52_set_bias_level(struct snd_soc_codec *codec,
regcache_cache_only(cs42l52->regmap, true); regcache_cache_only(cs42l52->regmap, true);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -956,7 +955,7 @@ static void cs42l52_beep_work(struct work_struct *work) ...@@ -956,7 +955,7 @@ static void cs42l52_beep_work(struct work_struct *work)
struct cs42l52_private *cs42l52 = struct cs42l52_private *cs42l52 =
container_of(work, struct cs42l52_private, beep_work); container_of(work, struct cs42l52_private, beep_work);
struct snd_soc_codec *codec = cs42l52->codec; struct snd_soc_codec *codec = cs42l52->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
int i; int i;
int val = 0; int val = 0;
int best = 0; int best = 0;
......
...@@ -953,7 +953,7 @@ static int cs42l56_set_bias_level(struct snd_soc_codec *codec, ...@@ -953,7 +953,7 @@ static int cs42l56_set_bias_level(struct snd_soc_codec *codec,
CS42L56_PDN_ALL_MASK, 0); CS42L56_PDN_ALL_MASK, 0);
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
regcache_cache_only(cs42l56->regmap, false); regcache_cache_only(cs42l56->regmap, false);
regcache_sync(cs42l56->regmap); regcache_sync(cs42l56->regmap);
ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies), ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies),
...@@ -978,7 +978,6 @@ static int cs42l56_set_bias_level(struct snd_soc_codec *codec, ...@@ -978,7 +978,6 @@ static int cs42l56_set_bias_level(struct snd_soc_codec *codec,
cs42l56->supplies); cs42l56->supplies);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -1026,7 +1025,7 @@ static void cs42l56_beep_work(struct work_struct *work) ...@@ -1026,7 +1025,7 @@ static void cs42l56_beep_work(struct work_struct *work)
struct cs42l56_private *cs42l56 = struct cs42l56_private *cs42l56 =
container_of(work, struct cs42l56_private, beep_work); container_of(work, struct cs42l56_private, beep_work);
struct snd_soc_codec *codec = cs42l56->codec; struct snd_soc_codec *codec = cs42l56->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
int i; int i;
int val = 0; int val = 0;
int best = 0; int best = 0;
......
...@@ -1208,7 +1208,7 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec, ...@@ -1208,7 +1208,7 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
regcache_cache_only(cs42l73->regmap, false); regcache_cache_only(cs42l73->regmap, false);
regcache_sync(cs42l73->regmap); regcache_sync(cs42l73->regmap);
} }
...@@ -1228,7 +1228,6 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec, ...@@ -1228,7 +1228,6 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 1); snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 1);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(cs42xx8_regmap_config); ...@@ -380,7 +380,7 @@ EXPORT_SYMBOL_GPL(cs42xx8_regmap_config);
static int cs42xx8_codec_probe(struct snd_soc_codec *codec) static int cs42xx8_codec_probe(struct snd_soc_codec *codec)
{ {
struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec); struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
switch (cs42xx8->drvdata->num_adcs) { switch (cs42xx8->drvdata->num_adcs) {
case 3: case 3:
......
...@@ -333,7 +333,7 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec, ...@@ -333,7 +333,7 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec,
switch (level) { switch (level) {
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
if (codec->dapm.bias_level != SND_SOC_BIAS_STANDBY) if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_STANDBY)
break; break;
if (IS_ERR(cx20442->por)) if (IS_ERR(cx20442->por))
err = PTR_ERR(cx20442->por); err = PTR_ERR(cx20442->por);
...@@ -341,7 +341,7 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec, ...@@ -341,7 +341,7 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec,
err = regulator_enable(cx20442->por); err = regulator_enable(cx20442->por);
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level != SND_SOC_BIAS_PREPARE) if (snd_soc_codec_get_bias_level(codec) != SND_SOC_BIAS_PREPARE)
break; break;
if (IS_ERR(cx20442->por)) if (IS_ERR(cx20442->por))
err = PTR_ERR(cx20442->por); err = PTR_ERR(cx20442->por);
...@@ -351,8 +351,6 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec, ...@@ -351,8 +351,6 @@ static int cx20442_set_bias_level(struct snd_soc_codec *codec,
default: default:
break; break;
} }
if (!err)
codec->dapm.bias_level = level;
return err; return err;
} }
......
...@@ -1374,7 +1374,7 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec, ...@@ -1374,7 +1374,7 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
/* Enable VMID reference & master bias */ /* Enable VMID reference & master bias */
snd_soc_update_bits(codec, DA7213_REFERENCES, snd_soc_update_bits(codec, DA7213_REFERENCES,
DA7213_VMID_EN | DA7213_BIAS_EN, DA7213_VMID_EN | DA7213_BIAS_EN,
...@@ -1387,7 +1387,6 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec, ...@@ -1387,7 +1387,6 @@ static int da7213_set_bias_level(struct snd_soc_codec *codec,
DA7213_VMID_EN | DA7213_BIAS_EN, 0); DA7213_VMID_EN | DA7213_BIAS_EN, 0);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -1432,7 +1432,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec, ...@@ -1432,7 +1432,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
/* Init Codec */ /* Init Codec */
snd_soc_write(codec, DA732X_REG_REF1, snd_soc_write(codec, DA732X_REG_REF1,
DA732X_VMID_FASTCHG); DA732X_VMID_FASTCHG);
...@@ -1502,8 +1502,6 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec, ...@@ -1502,8 +1502,6 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -1364,7 +1364,7 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec, ...@@ -1364,7 +1364,7 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
/* Enable VMID reference & master bias */ /* Enable VMID reference & master bias */
snd_soc_update_bits(codec, DA9055_REFERENCES, snd_soc_update_bits(codec, DA9055_REFERENCES,
DA9055_VMID_EN | DA9055_BIAS_EN, DA9055_VMID_EN | DA9055_BIAS_EN,
...@@ -1377,7 +1377,6 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec, ...@@ -1377,7 +1377,6 @@ static int da9055_set_bias_level(struct snd_soc_codec *codec,
DA9055_VMID_EN | DA9055_BIAS_EN, 0); DA9055_VMID_EN | DA9055_BIAS_EN, 0);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -536,7 +536,7 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec, ...@@ -536,7 +536,7 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
snd_soc_update_bits(codec, ES8328_CONTROL1, snd_soc_update_bits(codec, ES8328_CONTROL1,
ES8328_CONTROL1_VMIDSEL_MASK | ES8328_CONTROL1_VMIDSEL_MASK |
ES8328_CONTROL1_ENREF, ES8328_CONTROL1_ENREF,
...@@ -566,7 +566,6 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec, ...@@ -566,7 +566,6 @@ static int es8328_set_bias_level(struct snd_soc_codec *codec,
0); 0);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -909,8 +909,6 @@ static int isabelle_set_bias_level(struct snd_soc_codec *codec, ...@@ -909,8 +909,6 @@ static int isabelle_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -258,7 +258,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, ...@@ -258,7 +258,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
/* The only way to clear the suspend flag is to reset the codec */ /* The only way to clear the suspend flag is to reset the codec */
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
jz4740_codec_wakeup(regmap); jz4740_codec_wakeup(regmap);
mask = JZ4740_CODEC_1_VREF_DISABLE | mask = JZ4740_CODEC_1_VREF_DISABLE |
...@@ -281,8 +281,6 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, ...@@ -281,8 +281,6 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -23,11 +23,6 @@ ...@@ -23,11 +23,6 @@
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/tlv.h> #include <sound/tlv.h>
struct lm4857 {
struct regmap *regmap;
uint8_t mode;
};
static const struct reg_default lm4857_default_regs[] = { static const struct reg_default lm4857_default_regs[] = {
{ 0x0, 0x00 }, { 0x0, 0x00 },
{ 0x1, 0x00 }, { 0x1, 0x00 },
...@@ -46,66 +41,33 @@ static const struct reg_default lm4857_default_regs[] = { ...@@ -46,66 +41,33 @@ static const struct reg_default lm4857_default_regs[] = {
#define LM4857_WAKEUP 5 #define LM4857_WAKEUP 5
#define LM4857_EPGAIN 4 #define LM4857_EPGAIN 4
static int lm4857_get_mode(struct snd_kcontrol *kcontrol, static const unsigned int lm4857_mode_values[] = {
struct snd_ctl_elem_value *ucontrol) 0,
{ 6,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 7,
struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); 8,
9,
ucontrol->value.integer.value[0] = lm4857->mode; };
return 0;
}
static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
uint8_t value = ucontrol->value.integer.value[0];
lm4857->mode = value;
if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F, value + 6);
return 1;
}
static int lm4857_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec);
switch (level) {
case SND_SOC_BIAS_ON:
regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F,
lm4857->mode + 6);
break;
case SND_SOC_BIAS_STANDBY:
regmap_update_bits(lm4857->regmap, LM4857_CTRL, 0x0F, 0);
break;
default:
break;
}
codec->dapm.bias_level = level;
return 0;
}
static const char *lm4857_mode[] = { static const char * const lm4857_mode_texts[] = {
"Off",
"Earpiece", "Earpiece",
"Loudspeaker", "Loudspeaker",
"Loudspeaker + Headphone", "Loudspeaker + Headphone",
"Headphone", "Headphone",
}; };
static SOC_ENUM_SINGLE_EXT_DECL(lm4857_mode_enum, lm4857_mode); static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(lm4857_mode_enum,
LM4857_CTRL, 0, 0xf, lm4857_mode_texts, lm4857_mode_values);
static const struct snd_kcontrol_new lm4857_mode_ctrl =
SOC_DAPM_ENUM("Mode", lm4857_mode_enum);
static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = { static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("IN"), SND_SOC_DAPM_INPUT("IN"),
SND_SOC_DAPM_DEMUX("Mode", SND_SOC_NOPM, 0, 0, &lm4857_mode_ctrl),
SND_SOC_DAPM_OUTPUT("LS"), SND_SOC_DAPM_OUTPUT("LS"),
SND_SOC_DAPM_OUTPUT("HP"), SND_SOC_DAPM_OUTPUT("HP"),
SND_SOC_DAPM_OUTPUT("EP"), SND_SOC_DAPM_OUTPUT("EP"),
...@@ -127,24 +89,18 @@ static const struct snd_kcontrol_new lm4857_controls[] = { ...@@ -127,24 +89,18 @@ static const struct snd_kcontrol_new lm4857_controls[] = {
LM4857_WAKEUP, 1, 0), LM4857_WAKEUP, 1, 0),
SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL, SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL,
LM4857_EPGAIN, 1, 0), LM4857_EPGAIN, 1, 0),
SOC_ENUM_EXT("Mode", lm4857_mode_enum,
lm4857_get_mode, lm4857_set_mode),
}; };
/* There is a demux between the input signal and the output signals.
* Currently there is no easy way to model it in ASoC and since it does not make
* much of a difference in practice simply connect the input direclty to the
* outputs. */
static const struct snd_soc_dapm_route lm4857_routes[] = { static const struct snd_soc_dapm_route lm4857_routes[] = {
{"LS", NULL, "IN"}, { "Mode", NULL, "IN" },
{"HP", NULL, "IN"}, { "LS", "Loudspeaker", "Mode" },
{"EP", NULL, "IN"}, { "LS", "Loudspeaker + Headphone", "Mode" },
{ "HP", "Headphone", "Mode" },
{ "HP", "Loudspeaker + Headphone", "Mode" },
{ "EP", "Earpiece", "Mode" },
}; };
static struct snd_soc_codec_driver soc_codec_dev_lm4857 = { static struct snd_soc_component_driver lm4857_component_driver = {
.set_bias_level = lm4857_set_bias_level,
.controls = lm4857_controls, .controls = lm4857_controls,
.num_controls = ARRAY_SIZE(lm4857_controls), .num_controls = ARRAY_SIZE(lm4857_controls),
.dapm_widgets = lm4857_dapm_widgets, .dapm_widgets = lm4857_dapm_widgets,
...@@ -167,25 +123,14 @@ static const struct regmap_config lm4857_regmap_config = { ...@@ -167,25 +123,14 @@ static const struct regmap_config lm4857_regmap_config = {
static int lm4857_i2c_probe(struct i2c_client *i2c, static int lm4857_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct lm4857 *lm4857; struct regmap *regmap;
lm4857 = devm_kzalloc(&i2c->dev, sizeof(*lm4857), GFP_KERNEL);
if (!lm4857)
return -ENOMEM;
i2c_set_clientdata(i2c, lm4857);
lm4857->regmap = devm_regmap_init_i2c(i2c, &lm4857_regmap_config);
if (IS_ERR(lm4857->regmap))
return PTR_ERR(lm4857->regmap);
return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0); regmap = devm_regmap_init_i2c(i2c, &lm4857_regmap_config);
} if (IS_ERR(regmap))
return PTR_ERR(regmap);
static int lm4857_i2c_remove(struct i2c_client *i2c) return devm_snd_soc_register_component(&i2c->dev,
{ &lm4857_component_driver, NULL, 0);
snd_soc_unregister_codec(&i2c->dev);
return 0;
} }
static const struct i2c_device_id lm4857_i2c_id[] = { static const struct i2c_device_id lm4857_i2c_id[] = {
...@@ -200,7 +145,6 @@ static struct i2c_driver lm4857_i2c_driver = { ...@@ -200,7 +145,6 @@ static struct i2c_driver lm4857_i2c_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = lm4857_i2c_probe, .probe = lm4857_i2c_probe,
.remove = lm4857_i2c_remove,
.id_table = lm4857_i2c_id, .id_table = lm4857_i2c_id,
}; };
......
...@@ -1271,7 +1271,7 @@ static int lm49453_set_bias_level(struct snd_soc_codec *codec, ...@@ -1271,7 +1271,7 @@ static int lm49453_set_bias_level(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
regcache_sync(lm49453->regmap); regcache_sync(lm49453->regmap);
snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG, snd_soc_update_bits(codec, LM49453_P0_PMC_SETUP_REG,
...@@ -1284,8 +1284,6 @@ static int lm49453_set_bias_level(struct snd_soc_codec *codec, ...@@ -1284,8 +1284,6 @@ static int lm49453_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -1571,7 +1571,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec, ...@@ -1571,7 +1571,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
regcache_sync(max98088->regmap); regcache_sync(max98088->regmap);
snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN, snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
...@@ -1584,7 +1584,6 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec, ...@@ -1584,7 +1584,6 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
regcache_mark_dirty(max98088->regmap); regcache_mark_dirty(max98088->regmap);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -1500,7 +1500,7 @@ static const struct snd_soc_dapm_route max98091_dapm_routes[] = { ...@@ -1500,7 +1500,7 @@ static const struct snd_soc_dapm_route max98091_dapm_routes[] = {
static int max98090_add_widgets(struct snd_soc_codec *codec) static int max98090_add_widgets(struct snd_soc_codec *codec)
{ {
struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
snd_soc_add_codec_controls(codec, max98090_snd_controls, snd_soc_add_codec_controls(codec, max98090_snd_controls,
ARRAY_SIZE(max98090_snd_controls)); ARRAY_SIZE(max98090_snd_controls));
...@@ -1798,16 +1798,17 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, ...@@ -1798,16 +1798,17 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
* away from ON. Disable the clock in that case, otherwise * away from ON. Disable the clock in that case, otherwise
* enable it. * enable it.
*/ */
if (!IS_ERR(max98090->mclk)) { if (IS_ERR(max98090->mclk))
if (codec->dapm.bias_level == SND_SOC_BIAS_ON) break;
clk_disable_unprepare(max98090->mclk);
else if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON)
clk_prepare_enable(max98090->mclk); clk_disable_unprepare(max98090->mclk);
} else
clk_prepare_enable(max98090->mclk);
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
ret = regcache_sync(max98090->regmap); ret = regcache_sync(max98090->regmap);
if (ret != 0) { if (ret != 0) {
dev_err(codec->dev, dev_err(codec->dev,
...@@ -1824,7 +1825,6 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, ...@@ -1824,7 +1825,6 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec,
regcache_mark_dirty(max98090->regmap); regcache_mark_dirty(max98090->regmap);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -2187,7 +2187,6 @@ static void max98090_jack_work(struct work_struct *work) ...@@ -2187,7 +2187,6 @@ static void max98090_jack_work(struct work_struct *work)
struct max98090_priv, struct max98090_priv,
jack_work.work); jack_work.work);
struct snd_soc_codec *codec = max98090->codec; struct snd_soc_codec *codec = max98090->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
int status = 0; int status = 0;
int reg; int reg;
...@@ -2266,8 +2265,6 @@ static void max98090_jack_work(struct work_struct *work) ...@@ -2266,8 +2265,6 @@ static void max98090_jack_work(struct work_struct *work)
snd_soc_jack_report(max98090->jack, status, snd_soc_jack_report(max98090->jack, status,
SND_JACK_HEADSET | SND_JACK_BTN_0); SND_JACK_HEADSET | SND_JACK_BTN_0);
snd_soc_dapm_sync(dapm);
} }
static irqreturn_t max98090_interrupt(int irq, void *data) static irqreturn_t max98090_interrupt(int irq, void *data)
...@@ -2422,6 +2419,8 @@ static int max98090_probe(struct snd_soc_codec *codec) ...@@ -2422,6 +2419,8 @@ static int max98090_probe(struct snd_soc_codec *codec)
struct max98090_cdata *cdata; struct max98090_cdata *cdata;
enum max98090_type devtype; enum max98090_type devtype;
int ret = 0; int ret = 0;
int err;
unsigned int micbias;
dev_dbg(codec->dev, "max98090_probe\n"); dev_dbg(codec->dev, "max98090_probe\n");
...@@ -2506,8 +2505,17 @@ static int max98090_probe(struct snd_soc_codec *codec) ...@@ -2506,8 +2505,17 @@ static int max98090_probe(struct snd_soc_codec *codec)
snd_soc_write(codec, M98090_REG_BIAS_CONTROL, snd_soc_write(codec, M98090_REG_BIAS_CONTROL,
M98090_VCM_MODE_MASK); M98090_VCM_MODE_MASK);
err = device_property_read_u32(codec->dev, "maxim,micbias", &micbias);
if (err) {
micbias = M98090_MBVSEL_2V8;
dev_info(codec->dev, "use default 2.8v micbias\n");
} else if (micbias < M98090_MBVSEL_2V2 || micbias > M98090_MBVSEL_2V8) {
dev_err(codec->dev, "micbias out of range 0x%x\n", micbias);
micbias = M98090_MBVSEL_2V8;
}
snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE, snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE,
M98090_MBVSEL_MASK, M98090_MBVSEL_2V8); M98090_MBVSEL_MASK, micbias);
max98090_add_widgets(codec); max98090_add_widgets(codec);
......
...@@ -1650,16 +1650,17 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec, ...@@ -1650,16 +1650,17 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
* away from ON. Disable the clock in that case, otherwise * away from ON. Disable the clock in that case, otherwise
* enable it. * enable it.
*/ */
if (!IS_ERR(max98095->mclk)) { if (IS_ERR(max98095->mclk))
if (codec->dapm.bias_level == SND_SOC_BIAS_ON) break;
clk_disable_unprepare(max98095->mclk);
else if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_ON)
clk_prepare_enable(max98095->mclk); clk_disable_unprepare(max98095->mclk);
} else
clk_prepare_enable(max98095->mclk);
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
ret = regcache_sync(max98095->regmap); ret = regcache_sync(max98095->regmap);
if (ret != 0) { if (ret != 0) {
...@@ -1678,7 +1679,6 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec, ...@@ -1678,7 +1679,6 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec,
regcache_mark_dirty(max98095->regmap); regcache_mark_dirty(max98095->regmap);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -2198,7 +2198,7 @@ static int max98095_suspend(struct snd_soc_codec *codec) ...@@ -2198,7 +2198,7 @@ static int max98095_suspend(struct snd_soc_codec *codec)
if (max98095->headphone_jack || max98095->mic_jack) if (max98095->headphone_jack || max98095->mic_jack)
max98095_jack_detect_disable(codec); max98095_jack_detect_disable(codec);
max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
return 0; return 0;
} }
...@@ -2208,7 +2208,7 @@ static int max98095_resume(struct snd_soc_codec *codec) ...@@ -2208,7 +2208,7 @@ static int max98095_resume(struct snd_soc_codec *codec)
struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
struct i2c_client *client = to_i2c_client(codec->dev); struct i2c_client *client = to_i2c_client(codec->dev);
max98095_set_bias_level(codec, SND_SOC_BIAS_STANDBY); snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY);
if (max98095->headphone_jack || max98095->mic_jack) { if (max98095->headphone_jack || max98095->mic_jack) {
max98095_jack_detect_enable(codec); max98095_jack_detect_enable(codec);
...@@ -2301,8 +2301,8 @@ static int max98095_probe(struct snd_soc_codec *codec) ...@@ -2301,8 +2301,8 @@ static int max98095_probe(struct snd_soc_codec *codec)
/* register an audio interrupt */ /* register an audio interrupt */
ret = request_threaded_irq(client->irq, NULL, ret = request_threaded_irq(client->irq, NULL,
max98095_report_jack, max98095_report_jack,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
"max98095", codec); IRQF_ONESHOT, "max98095", codec);
if (ret) { if (ret) {
dev_err(codec->dev, "Failed to request IRQ: %d\n", ret); dev_err(codec->dev, "Failed to request IRQ: %d\n", ret);
goto err_access; goto err_access;
......
...@@ -60,13 +60,12 @@ static int max98357a_codec_probe(struct snd_soc_codec *codec) ...@@ -60,13 +60,12 @@ static int max98357a_codec_probe(struct snd_soc_codec *codec)
{ {
struct gpio_desc *sdmode; struct gpio_desc *sdmode;
sdmode = devm_gpiod_get(codec->dev, "sdmode"); sdmode = devm_gpiod_get(codec->dev, "sdmode", GPIOD_OUT_LOW);
if (IS_ERR(sdmode)) { if (IS_ERR(sdmode)) {
dev_err(codec->dev, "%s() unable to get sdmode GPIO: %ld\n", dev_err(codec->dev, "%s() unable to get sdmode GPIO: %ld\n",
__func__, PTR_ERR(sdmode)); __func__, PTR_ERR(sdmode));
return PTR_ERR(sdmode); return PTR_ERR(sdmode);
} }
gpiod_direction_output(sdmode, 0);
snd_soc_codec_set_drvdata(codec, sdmode); snd_soc_codec_set_drvdata(codec, sdmode);
return 0; return 0;
......
...@@ -252,7 +252,7 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec, ...@@ -252,7 +252,7 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
ret = regcache_sync(max9850->regmap); ret = regcache_sync(max9850->regmap);
if (ret) { if (ret) {
dev_err(codec->dev, dev_err(codec->dev,
...@@ -264,7 +264,6 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec, ...@@ -264,7 +264,6 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -523,7 +523,7 @@ static int ml26124_set_bias_level(struct snd_soc_codec *codec, ...@@ -523,7 +523,7 @@ static int ml26124_set_bias_level(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
/* VMID ON */ /* VMID ON */
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG, snd_soc_update_bits(codec, ML26124_PW_REF_PW_MNG,
ML26124_VMID, ML26124_VMID); ML26124_VMID, ML26124_VMID);
msleep(500); msleep(500);
...@@ -536,7 +536,6 @@ static int ml26124_set_bias_level(struct snd_soc_codec *codec, ...@@ -536,7 +536,6 @@ static int ml26124_set_bias_level(struct snd_soc_codec *codec,
ML26124_VMID, 0); ML26124_VMID, 0);
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -242,7 +242,7 @@ static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol, ...@@ -242,7 +242,7 @@ static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
switch (codec->dapm.bias_level) { switch (snd_soc_codec_get_bias_level(codec)) {
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
break; break;
...@@ -270,7 +270,7 @@ static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol, ...@@ -270,7 +270,7 @@ static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
switch (codec->dapm.bias_level) { switch (snd_soc_codec_get_bias_level(codec)) {
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
break; break;
...@@ -298,7 +298,7 @@ static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol, ...@@ -298,7 +298,7 @@ static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec); struct pcm512x_priv *pcm512x = snd_soc_codec_get_drvdata(codec);
switch (codec->dapm.bias_level) { switch (snd_soc_codec_get_bias_level(codec)) {
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
break; break;
...@@ -641,8 +641,6 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec, ...@@ -641,8 +641,6 @@ static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -301,6 +301,7 @@ static int rt286_support_power_controls[] = { ...@@ -301,6 +301,7 @@ static int rt286_support_power_controls[] = {
static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
{ {
struct snd_soc_dapm_context *dapm;
unsigned int val, buf; unsigned int val, buf;
*hp = false; *hp = false;
...@@ -308,6 +309,9 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) ...@@ -308,6 +309,9 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
if (!rt286->codec) if (!rt286->codec)
return -EINVAL; return -EINVAL;
dapm = snd_soc_codec_get_dapm(rt286->codec);
if (rt286->pdata.cbj_en) { if (rt286->pdata.cbj_en) {
regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
*hp = buf & 0x80000000; *hp = buf & 0x80000000;
...@@ -316,14 +320,11 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) ...@@ -316,14 +320,11 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
regmap_update_bits(rt286->regmap, regmap_update_bits(rt286->regmap,
RT286_DC_GAIN, 0x200, 0x200); RT286_DC_GAIN, 0x200, 0x200);
snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, snd_soc_dapm_force_enable_pin(dapm, "HV");
"HV"); snd_soc_dapm_force_enable_pin(dapm, "VREF");
snd_soc_dapm_force_enable_pin(&rt286->codec->dapm,
"VREF");
/* power LDO1 */ /* power LDO1 */
snd_soc_dapm_force_enable_pin(&rt286->codec->dapm, snd_soc_dapm_force_enable_pin(dapm, "LDO1");
"LDO1"); snd_soc_dapm_sync(dapm);
snd_soc_dapm_sync(&rt286->codec->dapm);
regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24); regmap_write(rt286->regmap, RT286_SET_MIC1, 0x24);
msleep(50); msleep(50);
...@@ -360,11 +361,11 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic) ...@@ -360,11 +361,11 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
*mic = buf & 0x80000000; *mic = buf & 0x80000000;
} }
snd_soc_dapm_disable_pin(&rt286->codec->dapm, "HV"); snd_soc_dapm_disable_pin(dapm, "HV");
snd_soc_dapm_disable_pin(&rt286->codec->dapm, "VREF"); snd_soc_dapm_disable_pin(dapm, "VREF");
if (!*hp) if (!*hp)
snd_soc_dapm_disable_pin(&rt286->codec->dapm, "LDO1"); snd_soc_dapm_disable_pin(dapm, "LDO1");
snd_soc_dapm_sync(&rt286->codec->dapm); snd_soc_dapm_sync(dapm);
return 0; return 0;
} }
...@@ -391,6 +392,7 @@ static void rt286_jack_detect_work(struct work_struct *work) ...@@ -391,6 +392,7 @@ static void rt286_jack_detect_work(struct work_struct *work)
int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec); struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
rt286->jack = jack; rt286->jack = jack;
...@@ -398,7 +400,7 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) ...@@ -398,7 +400,7 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
if (jack) { if (jack) {
/* enable IRQ */ /* enable IRQ */
if (rt286->jack->status & SND_JACK_HEADPHONE) if (rt286->jack->status & SND_JACK_HEADPHONE)
snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO1"); snd_soc_dapm_force_enable_pin(dapm, "LDO1");
regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2); regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x2);
/* Send an initial empty report */ /* Send an initial empty report */
snd_soc_jack_report(rt286->jack, rt286->jack->status, snd_soc_jack_report(rt286->jack, rt286->jack->status,
...@@ -406,9 +408,9 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) ...@@ -406,9 +408,9 @@ int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
} else { } else {
/* disable IRQ */ /* disable IRQ */
regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x0); regmap_update_bits(rt286->regmap, RT286_IRQ_CTRL, 0x2, 0x0);
snd_soc_dapm_disable_pin(&codec->dapm, "LDO1"); snd_soc_dapm_disable_pin(dapm, "LDO1");
} }
snd_soc_dapm_sync(&codec->dapm); snd_soc_dapm_sync(dapm);
return 0; return 0;
} }
...@@ -985,7 +987,7 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec, ...@@ -985,7 +987,7 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
{ {
switch (level) { switch (level) {
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) { if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
snd_soc_write(codec, snd_soc_write(codec,
RT286_SET_AUDIO_POWER, AC_PWRST_D0); RT286_SET_AUDIO_POWER, AC_PWRST_D0);
snd_soc_update_bits(codec, snd_soc_update_bits(codec,
...@@ -1012,7 +1014,6 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec, ...@@ -1012,7 +1014,6 @@ static int rt286_set_bias_level(struct snd_soc_codec *codec,
default: default:
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -1546,7 +1546,7 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec, ...@@ -1546,7 +1546,7 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS, RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS); RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
...@@ -1569,7 +1569,6 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec, ...@@ -1569,7 +1569,6 @@ static int rt5631_set_bias_level(struct snd_soc_codec *codec,
default: default:
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -1615,7 +1614,7 @@ static int rt5631_probe(struct snd_soc_codec *codec) ...@@ -1615,7 +1614,7 @@ static int rt5631_probe(struct snd_soc_codec *codec)
RT5631_DMIC_R_CH_LATCH_RISING); RT5631_DMIC_R_CH_LATCH_RISING);
} }
codec->dapm.bias_level = SND_SOC_BIAS_STANDBY; snd_soc_codec_init_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0; return 0;
} }
......
...@@ -1870,7 +1870,7 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec, ...@@ -1870,7 +1870,7 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
{ {
switch (level) { switch (level) {
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { if (SND_SOC_BIAS_OFF == snd_soc_codec_get_bias_level(codec)) {
snd_soc_update_bits(codec, RT5640_PWR_ANLG1, snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
RT5640_PWR_VREF1 | RT5640_PWR_MB | RT5640_PWR_VREF1 | RT5640_PWR_MB |
RT5640_PWR_BG | RT5640_PWR_VREF2, RT5640_PWR_BG | RT5640_PWR_VREF2,
...@@ -1902,7 +1902,6 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec, ...@@ -1902,7 +1902,6 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
default: default:
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -1935,11 +1934,12 @@ EXPORT_SYMBOL_GPL(rt5640_dmic_enable); ...@@ -1935,11 +1934,12 @@ EXPORT_SYMBOL_GPL(rt5640_dmic_enable);
static int rt5640_probe(struct snd_soc_codec *codec) static int rt5640_probe(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
rt5640->codec = codec; rt5640->codec = codec;
rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030); snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
...@@ -1951,18 +1951,18 @@ static int rt5640_probe(struct snd_soc_codec *codec) ...@@ -1951,18 +1951,18 @@ static int rt5640_probe(struct snd_soc_codec *codec)
snd_soc_add_codec_controls(codec, snd_soc_add_codec_controls(codec,
rt5640_specific_snd_controls, rt5640_specific_snd_controls,
ARRAY_SIZE(rt5640_specific_snd_controls)); ARRAY_SIZE(rt5640_specific_snd_controls));
snd_soc_dapm_new_controls(&codec->dapm, snd_soc_dapm_new_controls(dapm,
rt5640_specific_dapm_widgets, rt5640_specific_dapm_widgets,
ARRAY_SIZE(rt5640_specific_dapm_widgets)); ARRAY_SIZE(rt5640_specific_dapm_widgets));
snd_soc_dapm_add_routes(&codec->dapm, snd_soc_dapm_add_routes(dapm,
rt5640_specific_dapm_routes, rt5640_specific_dapm_routes,
ARRAY_SIZE(rt5640_specific_dapm_routes)); ARRAY_SIZE(rt5640_specific_dapm_routes));
break; break;
case RT5640_ID_5639: case RT5640_ID_5639:
snd_soc_dapm_new_controls(&codec->dapm, snd_soc_dapm_new_controls(dapm,
rt5639_specific_dapm_widgets, rt5639_specific_dapm_widgets,
ARRAY_SIZE(rt5639_specific_dapm_widgets)); ARRAY_SIZE(rt5639_specific_dapm_widgets));
snd_soc_dapm_add_routes(&codec->dapm, snd_soc_dapm_add_routes(dapm,
rt5639_specific_dapm_routes, rt5639_specific_dapm_routes,
ARRAY_SIZE(rt5639_specific_dapm_routes)); ARRAY_SIZE(rt5639_specific_dapm_routes));
break; break;
...@@ -1991,7 +1991,7 @@ static int rt5640_suspend(struct snd_soc_codec *codec) ...@@ -1991,7 +1991,7 @@ static int rt5640_suspend(struct snd_soc_codec *codec)
{ {
struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
rt5640_reset(codec); rt5640_reset(codec);
regcache_cache_only(rt5640->regmap, true); regcache_cache_only(rt5640->regmap, true);
regcache_mark_dirty(rt5640->regmap); regcache_mark_dirty(rt5640->regmap);
......
此差异已折叠。
...@@ -105,6 +105,7 @@ ...@@ -105,6 +105,7 @@
#define RT5645_TDM_CTRL_1 0x77 #define RT5645_TDM_CTRL_1 0x77
#define RT5645_TDM_CTRL_2 0x78 #define RT5645_TDM_CTRL_2 0x78
#define RT5645_TDM_CTRL_3 0x79 #define RT5645_TDM_CTRL_3 0x79
#define RT5650_TDM_CTRL_4 0x7a
/* Function - Analog */ /* Function - Analog */
#define RT5645_GLB_CLK 0x80 #define RT5645_GLB_CLK 0x80
...@@ -942,10 +943,6 @@ ...@@ -942,10 +943,6 @@
#define RT5645_I2S2_SDI_I2S2 (0x1 << 6) #define RT5645_I2S2_SDI_I2S2 (0x1 << 6)
/* ADC/DAC Clock Control 1 (0x73) */ /* ADC/DAC Clock Control 1 (0x73) */
#define RT5645_I2S_BCLK_MS1_MASK (0x1 << 15)
#define RT5645_I2S_BCLK_MS1_SFT 15
#define RT5645_I2S_BCLK_MS1_32 (0x0 << 15)
#define RT5645_I2S_BCLK_MS1_64 (0x1 << 15)
#define RT5645_I2S_PD1_MASK (0x7 << 12) #define RT5645_I2S_PD1_MASK (0x7 << 12)
#define RT5645_I2S_PD1_SFT 12 #define RT5645_I2S_PD1_SFT 12
#define RT5645_I2S_PD1_1 (0x0 << 12) #define RT5645_I2S_PD1_1 (0x0 << 12)
...@@ -1067,13 +1064,14 @@ ...@@ -1067,13 +1064,14 @@
#define RT5645_SCLK_SRC_SFT 14 #define RT5645_SCLK_SRC_SFT 14
#define RT5645_SCLK_SRC_MCLK (0x0 << 14) #define RT5645_SCLK_SRC_MCLK (0x0 << 14)
#define RT5645_SCLK_SRC_PLL1 (0x1 << 14) #define RT5645_SCLK_SRC_PLL1 (0x1 << 14)
#define RT5645_SCLK_SRC_RCCLK (0x2 << 14) /* 15MHz */ #define RT5645_SCLK_SRC_RCCLK (0x2 << 14)
#define RT5645_PLL1_SRC_MASK (0x3 << 12) #define RT5645_PLL1_SRC_MASK (0x7 << 11)
#define RT5645_PLL1_SRC_SFT 12 #define RT5645_PLL1_SRC_SFT 11
#define RT5645_PLL1_SRC_MCLK (0x0 << 12) #define RT5645_PLL1_SRC_MCLK (0x0 << 11)
#define RT5645_PLL1_SRC_BCLK1 (0x1 << 12) #define RT5645_PLL1_SRC_BCLK1 (0x1 << 11)
#define RT5645_PLL1_SRC_BCLK2 (0x2 << 12) #define RT5645_PLL1_SRC_BCLK2 (0x2 << 11)
#define RT5645_PLL1_SRC_BCLK3 (0x3 << 12) #define RT5645_PLL1_SRC_BCLK3 (0x3 << 11)
#define RT5645_PLL1_SRC_RCCLK (0x4 << 11)
#define RT5645_PLL1_PD_MASK (0x1 << 3) #define RT5645_PLL1_PD_MASK (0x1 << 3)
#define RT5645_PLL1_PD_SFT 3 #define RT5645_PLL1_PD_SFT 3
#define RT5645_PLL1_PD_1 (0x0 << 3) #define RT5645_PLL1_PD_1 (0x0 << 3)
...@@ -2147,6 +2145,7 @@ enum { ...@@ -2147,6 +2145,7 @@ enum {
}; };
enum { enum {
RT5645_DMIC1_DISABLE,
RT5645_DMIC_DATA_IN2P, RT5645_DMIC_DATA_IN2P,
RT5645_DMIC_DATA_GPIO6, RT5645_DMIC_DATA_GPIO6,
RT5645_DMIC_DATA_GPIO10, RT5645_DMIC_DATA_GPIO10,
...@@ -2154,6 +2153,7 @@ enum { ...@@ -2154,6 +2153,7 @@ enum {
}; };
enum { enum {
RT5645_DMIC2_DISABLE,
RT5645_DMIC_DATA_IN2N, RT5645_DMIC_DATA_IN2N,
RT5645_DMIC_DATA_GPIO5, RT5645_DMIC_DATA_GPIO5,
RT5645_DMIC_DATA_GPIO11, RT5645_DMIC_DATA_GPIO11,
...@@ -2184,6 +2184,7 @@ struct rt5645_priv { ...@@ -2184,6 +2184,7 @@ struct rt5645_priv {
struct i2c_client *i2c; struct i2c_client *i2c;
struct snd_soc_jack *hp_jack; struct snd_soc_jack *hp_jack;
struct snd_soc_jack *mic_jack; struct snd_soc_jack *mic_jack;
struct snd_soc_jack *btn_jack;
struct delayed_work jack_detect_work; struct delayed_work jack_detect_work;
int codec_type; int codec_type;
...@@ -2196,9 +2197,12 @@ struct rt5645_priv { ...@@ -2196,9 +2197,12 @@ struct rt5645_priv {
int pll_src; int pll_src;
int pll_in; int pll_in;
int pll_out; int pll_out;
int jack_type;
bool en_button_func;
}; };
int rt5645_set_jack_detect(struct snd_soc_codec *codec, int rt5645_set_jack_detect(struct snd_soc_codec *codec,
struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack); struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack,
struct snd_soc_jack *btn_jack);
#endif /* __RT5645_H__ */ #endif /* __RT5645_H__ */
...@@ -1571,7 +1571,7 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec, ...@@ -1571,7 +1571,7 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
{ {
switch (level) { switch (level) {
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) { if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
snd_soc_update_bits(codec, RT5651_PWR_ANLG1, snd_soc_update_bits(codec, RT5651_PWR_ANLG1,
RT5651_PWR_VREF1 | RT5651_PWR_MB | RT5651_PWR_VREF1 | RT5651_PWR_MB |
RT5651_PWR_BG | RT5651_PWR_VREF2, RT5651_PWR_BG | RT5651_PWR_VREF2,
...@@ -1604,7 +1604,6 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec, ...@@ -1604,7 +1604,6 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
default: default:
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
...@@ -1625,7 +1624,7 @@ static int rt5651_probe(struct snd_soc_codec *codec) ...@@ -1625,7 +1624,7 @@ static int rt5651_probe(struct snd_soc_codec *codec)
RT5651_PWR_FV1 | RT5651_PWR_FV2, RT5651_PWR_FV1 | RT5651_PWR_FV2,
RT5651_PWR_FV1 | RT5651_PWR_FV2); RT5651_PWR_FV1 | RT5651_PWR_FV2);
rt5651_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
return 0; return 0;
} }
......
...@@ -416,12 +416,12 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg) ...@@ -416,12 +416,12 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg)
static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert) static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
{ {
int val; int val;
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
if (jack_insert) { if (jack_insert) {
snd_soc_dapm_force_enable_pin(&codec->dapm, snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power");
"Mic Det Power"); snd_soc_dapm_sync(dapm);
snd_soc_dapm_sync(&codec->dapm);
snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0); snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
snd_soc_update_bits(codec, RT5670_CJ_CTRL2, snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD, RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
...@@ -447,15 +447,15 @@ static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert) ...@@ -447,15 +447,15 @@ static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
} else { } else {
snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4); snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
rt5670->jack_type = SND_JACK_HEADPHONE; rt5670->jack_type = SND_JACK_HEADPHONE;
snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power"); snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
snd_soc_dapm_sync(&codec->dapm); snd_soc_dapm_sync(dapm);
} }
} else { } else {
snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0); snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0);
snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4); snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
rt5670->jack_type = 0; rt5670->jack_type = 0;
snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power"); snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
snd_soc_dapm_sync(&codec->dapm); snd_soc_dapm_sync(dapm);
} }
return rt5670->jack_type; return rt5670->jack_type;
...@@ -2603,7 +2603,7 @@ static int rt5670_set_bias_level(struct snd_soc_codec *codec, ...@@ -2603,7 +2603,7 @@ static int rt5670_set_bias_level(struct snd_soc_codec *codec,
switch (level) { switch (level) {
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) { if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
snd_soc_update_bits(codec, RT5670_PWR_ANLG1, snd_soc_update_bits(codec, RT5670_PWR_ANLG1,
RT5670_PWR_VREF1 | RT5670_PWR_MB | RT5670_PWR_VREF1 | RT5670_PWR_MB |
RT5670_PWR_BG | RT5670_PWR_VREF2, RT5670_PWR_BG | RT5670_PWR_VREF2,
...@@ -2647,30 +2647,30 @@ static int rt5670_set_bias_level(struct snd_soc_codec *codec, ...@@ -2647,30 +2647,30 @@ static int rt5670_set_bias_level(struct snd_soc_codec *codec,
default: default:
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
static int rt5670_probe(struct snd_soc_codec *codec) static int rt5670_probe(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
switch (snd_soc_read(codec, RT5670_RESET) & RT5670_ID_MASK) { switch (snd_soc_read(codec, RT5670_RESET) & RT5670_ID_MASK) {
case RT5670_ID_5670: case RT5670_ID_5670:
case RT5670_ID_5671: case RT5670_ID_5671:
snd_soc_dapm_new_controls(&codec->dapm, snd_soc_dapm_new_controls(dapm,
rt5670_specific_dapm_widgets, rt5670_specific_dapm_widgets,
ARRAY_SIZE(rt5670_specific_dapm_widgets)); ARRAY_SIZE(rt5670_specific_dapm_widgets));
snd_soc_dapm_add_routes(&codec->dapm, snd_soc_dapm_add_routes(dapm,
rt5670_specific_dapm_routes, rt5670_specific_dapm_routes,
ARRAY_SIZE(rt5670_specific_dapm_routes)); ARRAY_SIZE(rt5670_specific_dapm_routes));
break; break;
case RT5670_ID_5672: case RT5670_ID_5672:
snd_soc_dapm_new_controls(&codec->dapm, snd_soc_dapm_new_controls(dapm,
rt5672_specific_dapm_widgets, rt5672_specific_dapm_widgets,
ARRAY_SIZE(rt5672_specific_dapm_widgets)); ARRAY_SIZE(rt5672_specific_dapm_widgets));
snd_soc_dapm_add_routes(&codec->dapm, snd_soc_dapm_add_routes(dapm,
rt5672_specific_dapm_routes, rt5672_specific_dapm_routes,
ARRAY_SIZE(rt5672_specific_dapm_routes)); ARRAY_SIZE(rt5672_specific_dapm_routes));
break; break;
......
此差异已折叠。
...@@ -1446,6 +1446,16 @@ ...@@ -1446,6 +1446,16 @@
#define RT5677_DSP_OB_4_7_CLK_SEL_MASK (0xf << 8) #define RT5677_DSP_OB_4_7_CLK_SEL_MASK (0xf << 8)
#define RT5677_DSP_OB_4_7_CLK_SEL_SFT 8 #define RT5677_DSP_OB_4_7_CLK_SEL_SFT 8
/* ASRC Control 8 (0x8a) */
#define RT5677_I2S1_CLK_SEL_MASK (0xf << 12)
#define RT5677_I2S1_CLK_SEL_SFT 12
#define RT5677_I2S2_CLK_SEL_MASK (0xf << 8)
#define RT5677_I2S2_CLK_SEL_SFT 8
#define RT5677_I2S3_CLK_SEL_MASK (0xf << 4)
#define RT5677_I2S3_CLK_SEL_SFT 4
#define RT5677_I2S4_CLK_SEL_MASK (0xf)
#define RT5677_I2S4_CLK_SEL_SFT 0
/* VAD Function Control 4 (0x9f) */ /* VAD Function Control 4 (0x9f) */
#define RT5677_VAD_SRC_MASK (0x7 << 8) #define RT5677_VAD_SRC_MASK (0x7 << 8)
#define RT5677_VAD_SRC_SFT 8 #define RT5677_VAD_SRC_SFT 8
...@@ -1744,6 +1754,10 @@ enum { ...@@ -1744,6 +1754,10 @@ enum {
RT5677_AD_MONO_R_FILTER = (0x1 << 12), RT5677_AD_MONO_R_FILTER = (0x1 << 12),
RT5677_DSP_OB_0_3_FILTER = (0x1 << 13), RT5677_DSP_OB_0_3_FILTER = (0x1 << 13),
RT5677_DSP_OB_4_7_FILTER = (0x1 << 14), RT5677_DSP_OB_4_7_FILTER = (0x1 << 14),
RT5677_I2S1_SOURCE = (0x1 << 15),
RT5677_I2S2_SOURCE = (0x1 << 16),
RT5677_I2S3_SOURCE = (0x1 << 17),
RT5677_I2S4_SOURCE = (0x1 << 18),
}; };
struct rt5677_priv { struct rt5677_priv {
...@@ -1762,6 +1776,7 @@ struct rt5677_priv { ...@@ -1762,6 +1776,7 @@ struct rt5677_priv {
int pll_in; int pll_in;
int pll_out; int pll_out;
int pow_ldo2; /* POW_LDO2 pin */ int pow_ldo2; /* POW_LDO2 pin */
int reset_pin; /* RESET pin */
enum rt5677_type type; enum rt5677_type type;
#ifdef CONFIG_GPIOLIB #ifdef CONFIG_GPIOLIB
struct gpio_chip gpio_chip; struct gpio_chip gpio_chip;
......
此差异已折叠。
...@@ -395,7 +395,7 @@ struct snd_soc_dai_driver sirf_audio_codec_dai = { ...@@ -395,7 +395,7 @@ struct snd_soc_dai_driver sirf_audio_codec_dai = {
static int sirf_audio_codec_probe(struct snd_soc_codec *codec) static int sirf_audio_codec_probe(struct snd_soc_codec *codec)
{ {
struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
pm_runtime_enable(codec->dev); pm_runtime_enable(codec->dev);
......
...@@ -194,7 +194,7 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, ...@@ -194,7 +194,7 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
pr_debug("vaud_bias powering up pll\n"); pr_debug("vaud_bias powering up pll\n");
/* power up the pll */ /* power up the pll */
snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5)); snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5));
...@@ -205,17 +205,22 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, ...@@ -205,17 +205,22 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { switch (snd_soc_codec_get_bias_level(codec)) {
case SND_SOC_BIAS_OFF:
pr_debug("vaud_bias power up rail\n"); pr_debug("vaud_bias power up rail\n");
/* power up the rail */ /* power up the rail */
snd_soc_write(codec, SN95031_VAUD, snd_soc_write(codec, SN95031_VAUD,
BIT(2)|BIT(1)|BIT(0)); BIT(2)|BIT(1)|BIT(0));
msleep(1); msleep(1);
} else if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) { break;
case SND_SOC_BIAS_PREPARE:
/* turn off pcm */ /* turn off pcm */
pr_debug("vaud_bias power dn pcm\n"); pr_debug("vaud_bias power dn pcm\n");
snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0); snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0);
snd_soc_write(codec, SN95031_AUDPLLCTRL, 0); snd_soc_write(codec, SN95031_AUDPLLCTRL, 0);
break;
default:
break;
} }
break; break;
...@@ -226,7 +231,6 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, ...@@ -226,7 +231,6 @@ static int sn95031_set_vaud_bias(struct snd_soc_codec *codec,
break; break;
} }
codec->dapm.bias_level = level;
return 0; return 0;
} }
......
...@@ -510,7 +510,7 @@ static int ssm2518_set_bias_level(struct snd_soc_codec *codec, ...@@ -510,7 +510,7 @@ static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_PREPARE:
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
ret = ssm2518_set_power(ssm2518, true); ret = ssm2518_set_power(ssm2518, true);
break; break;
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
...@@ -518,12 +518,7 @@ static int ssm2518_set_bias_level(struct snd_soc_codec *codec, ...@@ -518,12 +518,7 @@ static int ssm2518_set_bias_level(struct snd_soc_codec *codec,
break; break;
} }
if (ret) return ret;
return ret;
codec->dapm.bias_level = level;
return 0;
} }
static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册