提交 4e25d30c 编写于 作者: T Takashi Iwai

Merge tag 'asoc-v4.11' of...

Merge tag 'asoc-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Updates for v4.11

Another release that's mainly focused on drivers rather than core
changes, highlights include:

 - A huge batch of updates to the Intel drivers, mainly around
   DisplayPort and HDMI with some additional board support too.
 - Channel mapping support for HDMI.
 - Support for AllWinner A31 and A33, Everest Semiconductor ES8328,
   Nuvoton NAU8540.
...@@ -24,6 +24,8 @@ Optional properties: ...@@ -24,6 +24,8 @@ Optional properties:
this parameter to choose where the clock from. this parameter to choose where the clock from.
- By default the clock is from TK pin, if the clock from RK pin, this - By default the clock is from TK pin, if the clock from RK pin, this
property is needed. property is needed.
- #sound-dai-cells: Should contain <0>.
- This property makes the SSC into an automatically registered DAI.
Examples: Examples:
- PDC transfer: - PDC transfer:
......
...@@ -2,8 +2,7 @@ Devicetree bindings for the Axentia TSE-850 audio complex ...@@ -2,8 +2,7 @@ Devicetree bindings for the Axentia TSE-850 audio complex
Required properties: Required properties:
- compatible: "axentia,tse850-pcm5142" - compatible: "axentia,tse850-pcm5142"
- axentia,ssc-controller: The phandle of the atmel SSC controller used as - axentia,cpu-dai: The phandle of the cpu dai.
cpu dai.
- axentia,audio-codec: The phandle of the PCM5142 codec. - axentia,audio-codec: The phandle of the PCM5142 codec.
- axentia,add-gpios: gpio specifier that controls the mixer. - axentia,add-gpios: gpio specifier that controls the mixer.
- axentia,loop1-gpios: gpio specifier that controls loop relays on channel 1. - axentia,loop1-gpios: gpio specifier that controls loop relays on channel 1.
...@@ -43,6 +42,12 @@ the PCM5142 codec. ...@@ -43,6 +42,12 @@ the PCM5142 codec.
Example: Example:
&ssc0 {
#sound-dai-cells = <0>;
status = "okay";
};
&i2c { &i2c {
codec: pcm5142@4c { codec: pcm5142@4c {
compatible = "ti,pcm5142"; compatible = "ti,pcm5142";
...@@ -77,7 +82,7 @@ Example: ...@@ -77,7 +82,7 @@ Example:
sound { sound {
compatible = "axentia,tse850-pcm5142"; compatible = "axentia,tse850-pcm5142";
axentia,ssc-controller = <&ssc0>; axentia,cpu-dai = <&ssc0>;
axentia,audio-codec = <&codec>; axentia,audio-codec = <&codec>;
axentia,add-gpios = <&pioA 8 GPIO_ACTIVE_LOW>; axentia,add-gpios = <&pioA 8 GPIO_ACTIVE_LOW>;
......
...@@ -4,7 +4,7 @@ This device supports both I2C and SPI. ...@@ -4,7 +4,7 @@ This device supports both I2C and SPI.
Required properties: Required properties:
- compatible : "everest,es8328" - compatible : Should be "everest,es8328" or "everest,es8388"
- DVDD-supply : Regulator providing digital core supply voltage 1.8 - 3.6V - DVDD-supply : Regulator providing digital core supply voltage 1.8 - 3.6V
- AVDD-supply : Regulator providing analog supply voltage 3.3V - AVDD-supply : Regulator providing analog supply voltage 3.3V
- PVDD-supply : Regulator providing digital IO supply voltage 1.8 - 3.6V - PVDD-supply : Regulator providing digital IO supply voltage 1.8 - 3.6V
......
...@@ -4,6 +4,7 @@ Required properties: ...@@ -4,6 +4,7 @@ Required properties:
- compatible = "mediatek,mt2701-audio"; - compatible = "mediatek,mt2701-audio";
- reg: register location and size - reg: register location and size
- interrupts: Should contain AFE interrupt - interrupts: Should contain AFE interrupt
- power-domains: should define the power domain
- clock-names: should have these clock names: - clock-names: should have these clock names:
"infra_sys_audio_clk", "infra_sys_audio_clk",
"top_audio_mux1_sel", "top_audio_mux1_sel",
...@@ -58,6 +59,7 @@ Example: ...@@ -58,6 +59,7 @@ Example:
<0 0x112A0000 0 0x20000>; <0 0x112A0000 0 0x20000>;
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>, interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>;
power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
clocks = <&infracfg CLK_INFRA_AUDIO>, clocks = <&infracfg CLK_INFRA_AUDIO>,
<&topckgen CLK_TOP_AUD_MUX1_SEL>, <&topckgen CLK_TOP_AUD_MUX1_SEL>,
<&topckgen CLK_TOP_AUD_MUX2_SEL>, <&topckgen CLK_TOP_AUD_MUX2_SEL>,
......
NAU85L40 audio CODEC
This device supports I2C only.
Required properties:
- compatible : "nuvoton,nau8540"
- reg : the I2C address of the device.
Example:
codec: nau8540@1c {
compatible = "nuvoton,nau8540";
reg = <0x1c>;
};
ROCKCHIP RK3288 with HDMI and analog audio
Required properties:
- compatible: "rockchip,rk3288-hdmi-analog"
- rockchip,model: The user-visible name of this sound complex
- rockchip,i2s-controller: The phandle of the Rockchip I2S controller that's
connected to the CODEC
- rockchip,audio-codec: The phandle of the analog audio codec.
- rockchip,routing: A list of the connections between audio components.
Each entry is a pair of strings, the first being the
connection's sink, the second being the connection's
source. For this driver the first string should always be
"Analog".
Optionnal properties:
- rockchip,hp-en-gpios = The phandle of the GPIO that power up/down the
headphone (when the analog output is an headphone).
- rockchip,hp-det-gpios = The phandle of the GPIO that detects the headphone
(when the analog output is an headphone).
- pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt
Example:
sound {
compatible = "rockchip,rockchip-audio-es8388";
rockchip,model = "Analog audio output";
rockchip,i2s-controller = <&i2s>;
rockchip,audio-codec = <&es8388>;
rockchip,routing = "Analog", "LOUT2",
"Analog", "ROUT2";
rockchip,hp-en-gpios = <&gpio8 0 GPIO_ACTIVE_HIGH>;
rockchip,hp-det-gpios = <&gpio7 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&headphone>;
};
...@@ -7,6 +7,7 @@ Required properties: ...@@ -7,6 +7,7 @@ Required properties:
- compatible: should be one of the followings - compatible: should be one of the followings
- "allwinner,sun4i-a10-i2s" - "allwinner,sun4i-a10-i2s"
- "allwinner,sun6i-a31-i2s"
- reg: physical base address of the controller and length of memory mapped - reg: physical base address of the controller and length of memory mapped
region. region.
- interrupts: should contain the I2S interrupt. - interrupts: should contain the I2S interrupt.
...@@ -19,6 +20,10 @@ Required properties: ...@@ -19,6 +20,10 @@ Required properties:
- "mod" : module clock for the I2S controller - "mod" : module clock for the I2S controller
- #sound-dai-cells : Must be equal to 0 - #sound-dai-cells : Must be equal to 0
Required properties for the following compatibles:
- "allwinner,sun6i-a31-i2s"
- resets: phandle to the reset line for this codec
Example: Example:
i2s0: i2s@01c22400 { i2s0: i2s@01c22400 {
......
Allwinner SUN8I audio codec
------------------------------------
On Sun8i-A33 SoCs, the audio is separated in different parts:
- A DAI driver. It uses the "sun4i-i2s" driver which is
documented here:
Documentation/devicetree/bindings/sound/sun4i-i2s.txt
- An analog part of the codec which is handled as PRCM registers.
See Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
- An digital part of the codec which is documented in this current
binding documentation.
- And finally, an audio card which links all the above components.
The simple-audio card will be used.
See Documentation/devicetree/bindings/sound/simple-card.txt
This bindings documentation exposes Sun8i codec (digital part).
Required properties:
- compatible: must be "allwinner,sun8i-a33-codec"
- reg: must contain the registers location and length
- interrupts: must contain the codec interrupt
- clocks: a list of phandle + clock-specifer pairs, one for each entry
in clock-names.
- clock-names: should contain followings:
- "bus": the parent APB clock for this controller
- "mod": the parent module clock
Here is an example to add a sound card and the codec binding on sun8i SoCs that
are similar to A33 using simple-card:
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "sun8i-a33-audio";
simple-audio-card,format = "i2s";
simple-audio-card,frame-master = <&link_codec>;
simple-audio-card,bitclock-master = <&link_codec>;
simple-audio-card,mclk-fs = <512>;
simple-audio-card,aux-devs = <&codec_analog>;
simple-audio-card,routing =
"Left DAC", "Digital Left DAC",
"Right DAC", "Digital Right DAC";
simple-audio-card,cpu {
sound-dai = <&dai>;
};
link_codec: simple-audio-card,codec {
sound-dai = <&codec>;
};
soc@01c00000 {
[...]
audio-codec@1c22e00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun8i-a33-codec";
reg = <0x01c22e00 0x400>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
clock-names = "bus", "mod";
};
};
...@@ -10,6 +10,7 @@ Required properties: ...@@ -10,6 +10,7 @@ Required properties:
- compatible : should be one of the following: - compatible : should be one of the following:
- "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC - "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC
- "allwinner,sun6i-a31-spdif": for the Allwinner A31 SoC - "allwinner,sun6i-a31-spdif": for the Allwinner A31 SoC
- "allwinner,sun8i-h3-spdif": for the Allwinner H3 SoC
- reg : Offset and length of the register set for the device. - reg : Offset and length of the register set for the device.
......
ZTE ZX296702 I2S controller ZTE ZX296702 I2S controller
Required properties: Required properties:
- compatible : Must be "zte,zx296702-i2s" - compatible : Must be one of:
"zte,zx296718-i2s", "zte,zx296702-i2s"
"zte,zx296702-i2s"
- reg : Must contain I2S core's registers location and length - reg : Must contain I2S core's registers location and length
- clocks : Pairs of phandle and specifier referencing the controller's clocks. - clocks : Pairs of phandle and specifier referencing the controller's clocks.
- clock-names: "tx" for the clock to the I2S interface. - clock-names: "wclk" for the wclk, "pclk" for the pclk to the I2S interface.
- dmas: Pairs of phandle and specifier for the DMA channel that is used by - dmas: Pairs of phandle and specifier for the DMA channel that is used by
the core. The core expects two dma channels for transmit. the core. The core expects two dma channels for transmit.
- dma-names : Must be "tx" and "rx" - dma-names : Must be "tx" and "rx"
...@@ -16,12 +18,12 @@ please check: ...@@ -16,12 +18,12 @@ please check:
* dma/dma.txt * dma/dma.txt
Example: Example:
i2s0: i2s0@0b005000 { i2s0: i2s@b005000 {
#sound-dai-cells = <0>; #sound-dai-cells = <0>;
compatible = "zte,zx296702-i2s"; compatible = "zte,zx296718-i2s", "zte,zx296702-i2s";
reg = <0x0b005000 0x1000>; reg = <0x0b005000 0x1000>;
clocks = <&lsp0clk ZX296702_I2S0_DIV>; clocks = <&audiocrm AUDIO_I2S0_WCLK>, <&audiocrm AUDIO_I2S0_PCLK>;
clock-names = "tx"; clock-names = "wclk", "pclk";
interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&dma 5>, <&dma 6>; dmas = <&dma 5>, <&dma 6>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
......
...@@ -106,9 +106,7 @@ static struct s3c_audio_pdata i2sv4_pdata = { ...@@ -106,9 +106,7 @@ static struct s3c_audio_pdata i2sv4_pdata = {
.dma_playback = DMACH_HSI_I2SV40_TX, .dma_playback = DMACH_HSI_I2SV40_TX,
.dma_capture = DMACH_HSI_I2SV40_RX, .dma_capture = DMACH_HSI_I2SV40_RX,
.type = { .type = {
.i2s = { .quirks = QUIRK_PRI_6CHAN,
.quirks = QUIRK_PRI_6CHAN,
},
}, },
}; };
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include <linux/of.h> #include <linux/of.h>
#include "../../sound/soc/atmel/atmel_ssc_dai.h"
/* Serialize access to ssc_list and user count */ /* Serialize access to ssc_list and user count */
static DEFINE_SPINLOCK(user_lock); static DEFINE_SPINLOCK(user_lock);
static LIST_HEAD(ssc_list); static LIST_HEAD(ssc_list);
...@@ -145,6 +147,49 @@ static inline const struct atmel_ssc_platform_data * __init ...@@ -145,6 +147,49 @@ static inline const struct atmel_ssc_platform_data * __init
platform_get_device_id(pdev)->driver_data; platform_get_device_id(pdev)->driver_data;
} }
#ifdef CONFIG_SND_ATMEL_SOC_SSC
static int ssc_sound_dai_probe(struct ssc_device *ssc)
{
struct device_node *np = ssc->pdev->dev.of_node;
int ret;
int id;
ssc->sound_dai = false;
if (!of_property_read_bool(np, "#sound-dai-cells"))
return 0;
id = of_alias_get_id(np, "ssc");
if (id < 0)
return id;
ret = atmel_ssc_set_audio(id);
ssc->sound_dai = !ret;
return ret;
}
static void ssc_sound_dai_remove(struct ssc_device *ssc)
{
if (!ssc->sound_dai)
return;
atmel_ssc_put_audio(of_alias_get_id(ssc->pdev->dev.of_node, "ssc"));
}
#else
static inline int ssc_sound_dai_probe(struct ssc_device *ssc)
{
if (of_property_read_bool(ssc->pdev->dev.of_node, "#sound-dai-cells"))
return -ENOTSUPP;
return 0;
}
static inline void ssc_sound_dai_remove(struct ssc_device *ssc)
{
}
#endif
static int ssc_probe(struct platform_device *pdev) static int ssc_probe(struct platform_device *pdev)
{ {
struct resource *regs; struct resource *regs;
...@@ -204,6 +249,9 @@ static int ssc_probe(struct platform_device *pdev) ...@@ -204,6 +249,9 @@ static int ssc_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n", dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n",
ssc->regs, ssc->irq); ssc->regs, ssc->irq);
if (ssc_sound_dai_probe(ssc))
dev_err(&pdev->dev, "failed to auto-setup ssc for audio\n");
return 0; return 0;
} }
...@@ -211,6 +259,8 @@ static int ssc_remove(struct platform_device *pdev) ...@@ -211,6 +259,8 @@ static int ssc_remove(struct platform_device *pdev)
{ {
struct ssc_device *ssc = platform_get_drvdata(pdev); struct ssc_device *ssc = platform_get_drvdata(pdev);
ssc_sound_dai_remove(ssc);
spin_lock(&user_lock); spin_lock(&user_lock);
list_del(&ssc->list); list_del(&ssc->list);
spin_unlock(&user_lock); spin_unlock(&user_lock);
......
...@@ -248,6 +248,7 @@ struct detailed_timing { ...@@ -248,6 +248,7 @@ struct detailed_timing {
# define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa /* 500 ms */ # define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa /* 500 ms */
#define DRM_ELD_SPEAKER 7 #define DRM_ELD_SPEAKER 7
# define DRM_ELD_SPEAKER_MASK 0x7f
# define DRM_ELD_SPEAKER_RLRC (1 << 6) # define DRM_ELD_SPEAKER_RLRC (1 << 6)
# define DRM_ELD_SPEAKER_FLRC (1 << 5) # define DRM_ELD_SPEAKER_FLRC (1 << 5)
# define DRM_ELD_SPEAKER_RC (1 << 4) # define DRM_ELD_SPEAKER_RC (1 << 4)
...@@ -413,6 +414,18 @@ static inline int drm_eld_size(const uint8_t *eld) ...@@ -413,6 +414,18 @@ static inline int drm_eld_size(const uint8_t *eld)
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4; return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
} }
/**
* drm_eld_get_spk_alloc - Get speaker allocation
* @eld: pointer to an ELD memory structure
*
* The returned value is the speakers mask. User has to use %DRM_ELD_SPEAKER
* field definitions to identify speakers.
*/
static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld)
{
return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK;
}
/** /**
* drm_eld_get_conn_type - Get device type hdmi/dp connected * drm_eld_get_conn_type - Get device type hdmi/dp connected
* @eld: pointer to an ELD memory structure * @eld: pointer to an ELD memory structure
......
...@@ -20,6 +20,7 @@ struct ssc_device { ...@@ -20,6 +20,7 @@ struct ssc_device {
int user; int user;
int irq; int irq;
bool clk_from_rk_pin; bool clk_from_rk_pin;
bool sound_dai;
}; };
struct ssc_device * __must_check ssc_request(unsigned int ssc_num); struct ssc_device * __must_check ssc_request(unsigned int ssc_num);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
extern void s3c64xx_ac97_setup_gpio(int); extern void s3c64xx_ac97_setup_gpio(int);
struct samsung_i2s { struct samsung_i2s_type {
/* If the Primary DAI has 5.1 Channels */ /* If the Primary DAI has 5.1 Channels */
#define QUIRK_PRI_6CHAN (1 << 0) #define QUIRK_PRI_6CHAN (1 << 0)
/* If the I2S block has a Stereo Overlay Channel */ /* If the I2S block has a Stereo Overlay Channel */
...@@ -47,7 +47,5 @@ struct s3c_audio_pdata { ...@@ -47,7 +47,5 @@ struct s3c_audio_pdata {
void *dma_capture; void *dma_capture;
void *dma_play_sec; void *dma_play_sec;
void *dma_capture_mic; void *dma_capture_mic;
union { struct samsung_i2s_type type;
struct samsung_i2s i2s;
} type;
}; };
...@@ -71,6 +71,7 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) ...@@ -71,6 +71,7 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
* @slave_id: Slave requester id for the DMA channel. * @slave_id: Slave requester id for the DMA channel.
* @filter_data: Custom DMA channel filter data, this will usually be used when * @filter_data: Custom DMA channel filter data, this will usually be used when
* requesting the DMA channel. * requesting the DMA channel.
* @chan_name: Custom channel name to use when requesting DMA channel.
* @fifo_size: FIFO size of the DAI controller in bytes * @fifo_size: FIFO size of the DAI controller in bytes
* @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now * @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now
*/ */
...@@ -80,6 +81,7 @@ struct snd_dmaengine_dai_dma_data { ...@@ -80,6 +81,7 @@ struct snd_dmaengine_dai_dma_data {
u32 maxburst; u32 maxburst;
unsigned int slave_id; unsigned int slave_id;
void *filter_data; void *filter_data;
const char *chan_name;
unsigned int fifo_size; unsigned int fifo_size;
unsigned int flags; unsigned int flags;
}; };
...@@ -105,6 +107,10 @@ void snd_dmaengine_pcm_set_config_from_dai_data( ...@@ -105,6 +107,10 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
* playback. * playback.
*/ */
#define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3) #define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
/*
* The PCM streams have custom channel names specified.
*/
#define SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME BIT(4)
/** /**
* struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM * struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
......
...@@ -34,11 +34,12 @@ int asoc_simple_card_set_dailink_name(struct device *dev, ...@@ -34,11 +34,12 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
int asoc_simple_card_parse_card_name(struct snd_soc_card *card, int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
char *prefix); char *prefix);
#define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai) \ #define asoc_simple_card_parse_clk_cpu(dev, node, dai_link, simple_dai) \
asoc_simple_card_parse_clk(node, dai_link->cpu_of_node, simple_dai) asoc_simple_card_parse_clk(dev, node, dai_link->cpu_of_node, simple_dai)
#define asoc_simple_card_parse_clk_codec(node, dai_link, simple_dai) \ #define asoc_simple_card_parse_clk_codec(dev, node, dai_link, simple_dai) \
asoc_simple_card_parse_clk(node, dai_link->codec_of_node, simple_dai) asoc_simple_card_parse_clk(dev, node, dai_link->codec_of_node, simple_dai)
int asoc_simple_card_parse_clk(struct device_node *node, int asoc_simple_card_parse_clk(struct device *dev,
struct device_node *node,
struct device_node *dai_of_node, struct device_node *dai_of_node,
struct asoc_simple_dai *simple_dai); struct asoc_simple_dai *simple_dai);
......
...@@ -256,6 +256,9 @@ struct snd_soc_dai_driver { ...@@ -256,6 +256,9 @@ struct snd_soc_dai_driver {
int (*resume)(struct snd_soc_dai *dai); int (*resume)(struct snd_soc_dai *dai);
/* compress dai */ /* compress dai */
int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num); int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
/* Optional Callback used at pcm creation*/
int (*pcm_new)(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai);
/* DAI is also used for the control bus */ /* DAI is also used for the control bus */
bool bus_control; bool bus_control;
......
...@@ -497,6 +497,8 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream); ...@@ -497,6 +497,8 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd, int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
unsigned int dai_fmt); unsigned int dai_fmt);
int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour);
/* Utility functions to get clock rates from various things */ /* Utility functions to get clock rates from various things */
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params); int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
...@@ -507,9 +509,6 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *parms); ...@@ -507,9 +509,6 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *parms);
int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream, int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
const struct snd_pcm_hardware *hw); const struct snd_pcm_hardware *hw);
int snd_soc_platform_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_platform *platform);
int soc_dai_hw_params(struct snd_pcm_substream *substream, int soc_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai); struct snd_soc_dai *dai);
...@@ -785,6 +784,10 @@ struct snd_soc_component_driver { ...@@ -785,6 +784,10 @@ struct snd_soc_component_driver {
int (*suspend)(struct snd_soc_component *); int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *); int (*resume)(struct snd_soc_component *);
/* pcm creation and destruction */
int (*pcm_new)(struct snd_soc_pcm_runtime *);
void (*pcm_free)(struct snd_pcm *);
/* DT */ /* DT */
int (*of_xlate_dai_name)(struct snd_soc_component *component, int (*of_xlate_dai_name)(struct snd_soc_component *component,
struct of_phandle_args *args, struct of_phandle_args *args,
...@@ -859,6 +862,8 @@ struct snd_soc_component { ...@@ -859,6 +862,8 @@ struct snd_soc_component {
void (*remove)(struct snd_soc_component *); void (*remove)(struct snd_soc_component *);
int (*suspend)(struct snd_soc_component *); int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *); int (*resume)(struct snd_soc_component *);
int (*pcm_new)(struct snd_soc_pcm_runtime *);
void (*pcm_free)(struct snd_pcm *);
/* machine specific init */ /* machine specific init */
int (*init)(struct snd_soc_component *component); int (*init)(struct snd_soc_component *component);
...@@ -941,20 +946,11 @@ struct snd_soc_platform_driver { ...@@ -941,20 +946,11 @@ struct snd_soc_platform_driver {
int (*pcm_new)(struct snd_soc_pcm_runtime *); int (*pcm_new)(struct snd_soc_pcm_runtime *);
void (*pcm_free)(struct snd_pcm *); void (*pcm_free)(struct snd_pcm *);
/*
* For platform caused delay reporting.
* Optional.
*/
snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
struct snd_soc_dai *);
/* platform stream pcm ops */ /* platform stream pcm ops */
const struct snd_pcm_ops *ops; const struct snd_pcm_ops *ops;
/* platform stream compress ops */ /* platform stream compress ops */
const struct snd_compr_ops *compr_ops; const struct snd_compr_ops *compr_ops;
int (*bespoke_trigger)(struct snd_pcm_substream *, int);
}; };
struct snd_soc_dai_link_component { struct snd_soc_dai_link_component {
...@@ -1099,6 +1095,8 @@ struct snd_soc_card { ...@@ -1099,6 +1095,8 @@ struct snd_soc_card {
const char *name; const char *name;
const char *long_name; const char *long_name;
const char *driver_name; const char *driver_name;
char dmi_longname[80];
struct device *dev; struct device *dev;
struct snd_card *snd_card; struct snd_card *snd_card;
struct module *owner; struct module *owner;
...@@ -1647,37 +1645,21 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform( ...@@ -1647,37 +1645,21 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
int snd_soc_util_init(void); int snd_soc_util_init(void);
void snd_soc_util_exit(void); void snd_soc_util_exit(void);
#define snd_soc_of_parse_card_name(card, propname) \ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
snd_soc_of_parse_card_name_from_node(card, NULL, propname) const char *propname);
int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card, int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
struct device_node *np, const char *propname);
const char *propname);
#define snd_soc_of_parse_audio_simple_widgets(card, propname)\
snd_soc_of_parse_audio_simple_widgets_from_node(card, NULL, propname)
int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
struct device_node *np,
const char *propname);
int snd_soc_of_parse_tdm_slot(struct device_node *np, int snd_soc_of_parse_tdm_slot(struct device_node *np,
unsigned int *tx_mask, unsigned int *tx_mask,
unsigned int *rx_mask, unsigned int *rx_mask,
unsigned int *slots, unsigned int *slots,
unsigned int *slot_width); unsigned int *slot_width);
#define snd_soc_of_parse_audio_prefix(card, codec_conf, of_node, propname) \ void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
snd_soc_of_parse_audio_prefix_from_node(card, NULL, codec_conf, \
of_node, propname)
void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card,
struct device_node *np,
struct snd_soc_codec_conf *codec_conf, struct snd_soc_codec_conf *codec_conf,
struct device_node *of_node, struct device_node *of_node,
const char *propname); const char *propname);
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
#define snd_soc_of_parse_audio_routing(card, propname) \ const char *propname);
snd_soc_of_parse_audio_routing_from_node(card, NULL, propname)
int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
struct device_node *np,
const char *propname);
unsigned int snd_soc_of_parse_daifmt(struct device_node *np, unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
const char *prefix, const char *prefix,
struct device_node **bitclkmaster, struct device_node **bitclkmaster,
......
...@@ -128,14 +128,17 @@ void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *ebus, ...@@ -128,14 +128,17 @@ void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *ebus,
{ {
struct hdac_stream *hstream = &stream->hstream; struct hdac_stream *hstream = &stream->hstream;
struct hdac_bus *bus = &ebus->bus; struct hdac_bus *bus = &ebus->bus;
u32 val;
int mask = AZX_PPCTL_PROCEN(hstream->index);
spin_lock_irq(&bus->reg_lock); spin_lock_irq(&bus->reg_lock);
if (decouple) val = readw(bus->ppcap + AZX_REG_PP_PPCTL) & mask;
snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0,
AZX_PPCTL_PROCEN(hstream->index)); if (decouple && !val)
else snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, mask, mask);
snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, else if (!decouple && val)
AZX_PPCTL_PROCEN(hstream->index), 0); snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, mask, 0);
stream->decoupled = decouple; stream->decoupled = decouple;
spin_unlock_irq(&bus->reg_lock); spin_unlock_irq(&bus->reg_lock);
} }
......
...@@ -670,13 +670,10 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream, ...@@ -670,13 +670,10 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
{ {
int status; int status;
uint64_t size; uint64_t size;
struct snd_dma_buffer *dma_buffer;
struct page *pg; struct page *pg;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
struct audio_substream_data *rtd; struct audio_substream_data *rtd;
dma_buffer = &substream->dma_buffer;
runtime = substream->runtime; runtime = substream->runtime;
rtd = runtime->private_data; rtd = runtime->private_data;
......
...@@ -51,11 +51,7 @@ ...@@ -51,11 +51,7 @@
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include "atmel_ssc_dai.h"
struct tse850_priv { struct tse850_priv {
int ssc_id;
struct gpio_desc *add; struct gpio_desc *add;
struct gpio_desc *loop1; struct gpio_desc *loop1;
struct gpio_desc *loop2; struct gpio_desc *loop2;
...@@ -329,23 +325,20 @@ static int tse850_dt_init(struct platform_device *pdev) ...@@ -329,23 +325,20 @@ static int tse850_dt_init(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct device_node *codec_np, *cpu_np; struct device_node *codec_np, *cpu_np;
struct snd_soc_card *card = &tse850_card;
struct snd_soc_dai_link *dailink = &tse850_dailink; struct snd_soc_dai_link *dailink = &tse850_dailink;
struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
if (!np) { if (!np) {
dev_err(&pdev->dev, "only device tree supported\n"); dev_err(&pdev->dev, "only device tree supported\n");
return -EINVAL; return -EINVAL;
} }
cpu_np = of_parse_phandle(np, "axentia,ssc-controller", 0); cpu_np = of_parse_phandle(np, "axentia,cpu-dai", 0);
if (!cpu_np) { if (!cpu_np) {
dev_err(&pdev->dev, "failed to get dai and pcm info\n"); dev_err(&pdev->dev, "failed to get cpu dai\n");
return -EINVAL; return -EINVAL;
} }
dailink->cpu_of_node = cpu_np; dailink->cpu_of_node = cpu_np;
dailink->platform_of_node = cpu_np; dailink->platform_of_node = cpu_np;
tse850->ssc_id = of_alias_get_id(cpu_np, "ssc");
of_node_put(cpu_np); of_node_put(cpu_np);
codec_np = of_parse_phandle(np, "axentia,audio-codec", 0); codec_np = of_parse_phandle(np, "axentia,audio-codec", 0);
...@@ -415,23 +408,14 @@ static int tse850_probe(struct platform_device *pdev) ...@@ -415,23 +408,14 @@ static int tse850_probe(struct platform_device *pdev)
return ret; return ret;
} }
ret = atmel_ssc_set_audio(tse850->ssc_id);
if (ret != 0) {
dev_err(dev,
"failed to set SSC %d for audio\n", tse850->ssc_id);
goto err_disable_ana;
}
ret = snd_soc_register_card(card); ret = snd_soc_register_card(card);
if (ret) { if (ret) {
dev_err(dev, "snd_soc_register_card failed\n"); dev_err(dev, "snd_soc_register_card failed\n");
goto err_put_audio; goto err_disable_ana;
} }
return 0; return 0;
err_put_audio:
atmel_ssc_put_audio(tse850->ssc_id);
err_disable_ana: err_disable_ana:
regulator_disable(tse850->ana); regulator_disable(tse850->ana);
return ret; return ret;
...@@ -443,7 +427,6 @@ static int tse850_remove(struct platform_device *pdev) ...@@ -443,7 +427,6 @@ static int tse850_remove(struct platform_device *pdev)
struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card); struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
snd_soc_unregister_card(card); snd_soc_unregister_card(card);
atmel_ssc_put_audio(tse850->ssc_id);
regulator_disable(tse850->ana); regulator_disable(tse850->ana);
return 0; return 0;
......
...@@ -45,7 +45,7 @@ config SND_SOC_ALL_CODECS ...@@ -45,7 +45,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_ALC5623 if I2C select SND_SOC_ALC5623 if I2C
select SND_SOC_ALC5632 if I2C select SND_SOC_ALC5632 if I2C
select SND_SOC_BT_SCO select SND_SOC_BT_SCO
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC select SND_SOC_CQ0093VC
select SND_SOC_CS35L32 if I2C select SND_SOC_CS35L32 if I2C
select SND_SOC_CS35L33 if I2C select SND_SOC_CS35L33 if I2C
select SND_SOC_CS35L34 if I2C select SND_SOC_CS35L34 if I2C
...@@ -95,6 +95,7 @@ config SND_SOC_ALL_CODECS ...@@ -95,6 +95,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9877 if I2C select SND_SOC_MAX9877 if I2C
select SND_SOC_MC13783 if MFD_MC13XXX select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C select SND_SOC_ML26124 if I2C
select SND_SOC_NAU8540 if I2C
select SND_SOC_NAU8810 if I2C select SND_SOC_NAU8810 if I2C
select SND_SOC_NAU8825 if I2C select SND_SOC_NAU8825 if I2C
select SND_SOC_HDMI_CODEC select SND_SOC_HDMI_CODEC
...@@ -117,8 +118,8 @@ config SND_SOC_ALL_CODECS ...@@ -117,8 +118,8 @@ config SND_SOC_ALL_CODECS
select SND_SOC_RT5651 if I2C select SND_SOC_RT5651 if I2C
select SND_SOC_RT5659 if I2C select SND_SOC_RT5659 if I2C
select SND_SOC_RT5660 if I2C select SND_SOC_RT5660 if I2C
select SND_SOC_RT5665 if I2C
select SND_SOC_RT5663 if I2C select SND_SOC_RT5663 if I2C
select SND_SOC_RT5665 if I2C
select SND_SOC_RT5670 if I2C select SND_SOC_RT5670 if I2C
select SND_SOC_RT5677 if I2C && SPI_MASTER select SND_SOC_RT5677 if I2C && SPI_MASTER
select SND_SOC_SGTL5000 if I2C select SND_SOC_SGTL5000 if I2C
...@@ -525,14 +526,16 @@ config SND_SOC_HDMI_CODEC ...@@ -525,14 +526,16 @@ config SND_SOC_HDMI_CODEC
select HDMI select HDMI
config SND_SOC_ES8328 config SND_SOC_ES8328
tristate "Everest Semi ES8328 CODEC" tristate
config SND_SOC_ES8328_I2C config SND_SOC_ES8328_I2C
tristate tristate "Everest Semi ES8328 CODEC (I2C)"
depends on I2C
select SND_SOC_ES8328 select SND_SOC_ES8328
config SND_SOC_ES8328_SPI config SND_SOC_ES8328_SPI
tristate tristate "Everest Semi ES8328 CODEC (SPI)"
depends on SPI_MASTER
select SND_SOC_ES8328 select SND_SOC_ES8328
config SND_SOC_GTM601 config SND_SOC_GTM601
...@@ -668,8 +671,8 @@ config SND_SOC_RL6231 ...@@ -668,8 +671,8 @@ config SND_SOC_RL6231
default y if SND_SOC_RT5651=y default y if SND_SOC_RT5651=y
default y if SND_SOC_RT5659=y default y if SND_SOC_RT5659=y
default y if SND_SOC_RT5660=y default y if SND_SOC_RT5660=y
default y if SND_SOC_RT5665=y
default y if SND_SOC_RT5663=y default y if SND_SOC_RT5663=y
default y if SND_SOC_RT5665=y
default y if SND_SOC_RT5670=y default y if SND_SOC_RT5670=y
default y if SND_SOC_RT5677=y default y if SND_SOC_RT5677=y
default m if SND_SOC_RT5514=m default m if SND_SOC_RT5514=m
...@@ -679,8 +682,8 @@ config SND_SOC_RL6231 ...@@ -679,8 +682,8 @@ config SND_SOC_RL6231
default m if SND_SOC_RT5651=m default m if SND_SOC_RT5651=m
default m if SND_SOC_RT5659=m default m if SND_SOC_RT5659=m
default m if SND_SOC_RT5660=m default m if SND_SOC_RT5660=m
default m if SND_SOC_RT5665=m
default m if SND_SOC_RT5663=m default m if SND_SOC_RT5663=m
default m if SND_SOC_RT5665=m
default m if SND_SOC_RT5670=m default m if SND_SOC_RT5670=m
default m if SND_SOC_RT5677=m default m if SND_SOC_RT5677=m
...@@ -728,10 +731,10 @@ config SND_SOC_RT5659 ...@@ -728,10 +731,10 @@ config SND_SOC_RT5659
config SND_SOC_RT5660 config SND_SOC_RT5660
tristate tristate
config SND_SOC_RT5665 config SND_SOC_RT5663
tristate tristate
config SND_SOC_RT5663 config SND_SOC_RT5665
tristate tristate
config SND_SOC_RT5670 config SND_SOC_RT5670
...@@ -1105,6 +1108,10 @@ config SND_SOC_MC13783 ...@@ -1105,6 +1108,10 @@ config SND_SOC_MC13783
config SND_SOC_ML26124 config SND_SOC_ML26124
tristate tristate
config SND_SOC_NAU8540
tristate "Nuvoton Technology Corporation NAU85L40 CODEC"
depends on I2C
config SND_SOC_NAU8810 config SND_SOC_NAU8810
tristate "Nuvoton Technology Corporation NAU88C10 CODEC" tristate "Nuvoton Technology Corporation NAU88C10 CODEC"
depends on I2C depends on I2C
......
...@@ -90,6 +90,7 @@ snd-soc-mc13783-objs := mc13783.o ...@@ -90,6 +90,7 @@ snd-soc-mc13783-objs := mc13783.o
snd-soc-ml26124-objs := ml26124.o snd-soc-ml26124-objs := ml26124.o
snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o
snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o
snd-soc-nau8540-objs := nau8540.o
snd-soc-nau8810-objs := nau8810.o snd-soc-nau8810-objs := nau8810.o
snd-soc-nau8825-objs := nau8825.o snd-soc-nau8825-objs := nau8825.o
snd-soc-hdmi-codec-objs := hdmi-codec.o snd-soc-hdmi-codec-objs := hdmi-codec.o
...@@ -118,8 +119,8 @@ snd-soc-rt5645-objs := rt5645.o ...@@ -118,8 +119,8 @@ snd-soc-rt5645-objs := rt5645.o
snd-soc-rt5651-objs := rt5651.o snd-soc-rt5651-objs := rt5651.o
snd-soc-rt5659-objs := rt5659.o snd-soc-rt5659-objs := rt5659.o
snd-soc-rt5660-objs := rt5660.o snd-soc-rt5660-objs := rt5660.o
snd-soc-rt5665-objs := rt5665.o
snd-soc-rt5663-objs := rt5663.o snd-soc-rt5663-objs := rt5663.o
snd-soc-rt5665-objs := rt5665.o
snd-soc-rt5670-objs := rt5670.o snd-soc-rt5670-objs := rt5670.o
snd-soc-rt5677-objs := rt5677.o snd-soc-rt5677-objs := rt5677.o
snd-soc-rt5677-spi-objs := rt5677-spi.o snd-soc-rt5677-spi-objs := rt5677-spi.o
...@@ -318,6 +319,7 @@ obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o ...@@ -318,6 +319,7 @@ obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o
obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o
obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o
obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
...@@ -346,8 +348,8 @@ obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o ...@@ -346,8 +348,8 @@ obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o
obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o
obj-$(CONFIG_SND_SOC_RT5660) += snd-soc-rt5660.o obj-$(CONFIG_SND_SOC_RT5660) += snd-soc-rt5660.o
obj-$(CONFIG_SND_SOC_RT5665) += snd-soc-rt5665.o
obj-$(CONFIG_SND_SOC_RT5663) += snd-soc-rt5663.o obj-$(CONFIG_SND_SOC_RT5663) += snd-soc-rt5663.o
obj-$(CONFIG_SND_SOC_RT5665) += snd-soc-rt5665.o
obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o
......
...@@ -65,7 +65,6 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w, ...@@ -65,7 +65,6 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
{ {
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct adau *adau = snd_soc_codec_get_drvdata(codec); struct adau *adau = snd_soc_codec_get_drvdata(codec);
int ret;
if (SND_SOC_DAPM_EVENT_ON(event)) { if (SND_SOC_DAPM_EVENT_ON(event)) {
adau->pll_regs[5] = 1; adau->pll_regs[5] = 1;
...@@ -78,7 +77,7 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w, ...@@ -78,7 +77,7 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
} }
/* The PLL register is 6 bytes long and can only be written at once. */ /* The PLL register is 6 bytes long and can only be written at once. */
ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL, regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
adau->pll_regs, ARRAY_SIZE(adau->pll_regs)); adau->pll_regs, ARRAY_SIZE(adau->pll_regs));
if (SND_SOC_DAPM_EVENT_ON(event)) { if (SND_SOC_DAPM_EVENT_ON(event)) {
......
...@@ -189,7 +189,7 @@ static int ak4642_lout_event(struct snd_soc_dapm_widget *w, ...@@ -189,7 +189,7 @@ static int ak4642_lout_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_POST_PMU:
case SND_SOC_DAPM_POST_PMD: case SND_SOC_DAPM_POST_PMD:
/* Power save mode OFF */ /* Power save mode OFF */
mdelay(300); msleep(300);
snd_soc_update_bits(codec, SG_SL2, LOPS, 0); snd_soc_update_bits(codec, SG_SL2, LOPS, 0);
break; break;
} }
......
...@@ -192,6 +192,7 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ...@@ -192,6 +192,7 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
#define ARIZONA_DSP_ROUTES(name) \ #define ARIZONA_DSP_ROUTES(name) \
{ name, NULL, name " Preloader"}, \ { name, NULL, name " Preloader"}, \
{ name " Preloader", NULL, "SYSCLK" }, \ { name " Preloader", NULL, "SYSCLK" }, \
{ name " Preload", NULL, name " Preloader"}, \
{ name, NULL, name " Aux 1" }, \ { name, NULL, name " Aux 1" }, \
{ name, NULL, name " Aux 2" }, \ { name, NULL, name " Aux 2" }, \
{ name, NULL, name " Aux 3" }, \ { name, NULL, name " Aux 3" }, \
......
...@@ -173,6 +173,9 @@ SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]), ...@@ -173,6 +173,9 @@ SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]), SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]),
SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1), SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
WM_ADSP2_PRELOAD_SWITCH("DSP2", 2),
WM_ADSP2_PRELOAD_SWITCH("DSP3", 3),
ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE),
...@@ -1121,7 +1124,10 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec) ...@@ -1121,7 +1124,10 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec)
priv->core.arizona->dapm = dapm; priv->core.arizona->dapm = dapm;
arizona_init_spk(codec); ret = arizona_init_spk(codec);
if (ret < 0)
return ret;
arizona_init_gpio(codec); arizona_init_gpio(codec);
arizona_init_mono(codec); arizona_init_mono(codec);
arizona_init_notifiers(codec); arizona_init_notifiers(codec);
......
...@@ -1634,7 +1634,8 @@ static const struct snd_soc_dapm_widget da7218_dapm_widgets[] = { ...@@ -1634,7 +1634,8 @@ static const struct snd_soc_dapm_widget da7218_dapm_widgets[] = {
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
/* DAI */ /* DAI */
SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, DA7218_DAI_TDM_CTRL,
DA7218_DAI_OE_SHIFT, DA7218_NO_INVERT),
SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0),
/* Output Mixers */ /* Output Mixers */
......
...@@ -20,12 +20,14 @@ ...@@ -20,12 +20,14 @@
static const struct i2c_device_id es8328_id[] = { static const struct i2c_device_id es8328_id[] = {
{ "es8328", 0 }, { "es8328", 0 },
{ "es8388", 0 },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, es8328_id); MODULE_DEVICE_TABLE(i2c, es8328_id);
static const struct of_device_id es8328_of_match[] = { static const struct of_device_id es8328_of_match[] = {
{ .compatible = "everest,es8328", }, { .compatible = "everest,es8328", },
{ .compatible = "everest,es8388", },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, es8328_of_match); MODULE_DEVICE_TABLE(of, es8328_of_match);
......
...@@ -589,9 +589,21 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -589,9 +589,21 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
u8 dac_mode = 0; u8 dac_mode = 0;
u8 adc_mode = 0; u8 adc_mode = 0;
/* set master/slave audio interface */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBM_CFM) case SND_SOC_DAIFMT_CBM_CFM:
/* Master serial port mode, with BCLK generated automatically */
snd_soc_update_bits(codec, ES8328_MASTERMODE,
ES8328_MASTERMODE_MSC,
ES8328_MASTERMODE_MSC);
break;
case SND_SOC_DAIFMT_CBS_CFS:
/* Slave serial port mode */
snd_soc_update_bits(codec, ES8328_MASTERMODE,
ES8328_MASTERMODE_MSC, 0);
break;
default:
return -EINVAL; return -EINVAL;
}
/* interface format */ /* interface format */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
...@@ -620,10 +632,6 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, ...@@ -620,10 +632,6 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
snd_soc_update_bits(codec, ES8328_ADCCONTROL4, snd_soc_update_bits(codec, ES8328_ADCCONTROL4,
ES8328_ADCCONTROL4_ADCFORMAT_MASK, adc_mode); ES8328_ADCCONTROL4_ADCFORMAT_MASK, adc_mode);
/* Master serial port mode, with BCLK generated automatically */
snd_soc_update_bits(codec, ES8328_MASTERMODE,
ES8328_MASTERMODE_MSC, ES8328_MASTERMODE_MSC);
return 0; return 0;
} }
......
此差异已折叠。
#ifndef __HDAC_HDMI_H__ #ifndef __HDAC_HDMI_H__
#define __HDAC_HDMI_H__ #define __HDAC_HDMI_H__
int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm); int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm,
struct snd_soc_jack *jack);
int hdac_hdmi_jack_port_init(struct snd_soc_codec *codec,
struct snd_soc_dapm_context *dapm);
#endif /* __HDAC_HDMI_H__ */ #endif /* __HDAC_HDMI_H__ */
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/tlv.h>
#include <sound/pcm_drm_eld.h> #include <sound/pcm_drm_eld.h>
#include <sound/hdmi-codec.h> #include <sound/hdmi-codec.h>
#include <sound/pcm_iec958.h> #include <sound/pcm_iec958.h>
...@@ -31,8 +32,261 @@ struct hdmi_device { ...@@ -31,8 +32,261 @@ struct hdmi_device {
}; };
#define pos_to_hdmi_device(pos) container_of((pos), struct hdmi_device, list) #define pos_to_hdmi_device(pos) container_of((pos), struct hdmi_device, list)
LIST_HEAD(hdmi_device_list); LIST_HEAD(hdmi_device_list);
static DEFINE_MUTEX(hdmi_mutex);
#define DAI_NAME_SIZE 16 #define DAI_NAME_SIZE 16
#define HDMI_CODEC_CHMAP_IDX_UNKNOWN -1
struct hdmi_codec_channel_map_table {
unsigned char map; /* ALSA API channel map position */
unsigned long spk_mask; /* speaker position bit mask */
};
/*
* CEA speaker placement for HDMI 1.4:
*
* FL FLC FC FRC FR FRW
*
* LFE
*
* RL RLC RC RRC RR
*
* Speaker placement has to be extended to support HDMI 2.0
*/
enum hdmi_codec_cea_spk_placement {
FL = BIT(0), /* Front Left */
FC = BIT(1), /* Front Center */
FR = BIT(2), /* Front Right */
FLC = BIT(3), /* Front Left Center */
FRC = BIT(4), /* Front Right Center */
RL = BIT(5), /* Rear Left */
RC = BIT(6), /* Rear Center */
RR = BIT(7), /* Rear Right */
RLC = BIT(8), /* Rear Left Center */
RRC = BIT(9), /* Rear Right Center */
LFE = BIT(10), /* Low Frequency Effect */
};
/*
* cea Speaker allocation structure
*/
struct hdmi_codec_cea_spk_alloc {
const int ca_id;
unsigned int n_ch;
unsigned long mask;
};
/* Channel maps stereo HDMI */
const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = {
{ .channels = 2,
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
{ }
};
/* Channel maps for multi-channel playbacks, up to 8 n_ch */
const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
{ .channels = 2, /* CA_ID 0x00 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
{ .channels = 4, /* CA_ID 0x01 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA } },
{ .channels = 4, /* CA_ID 0x02 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC } },
{ .channels = 4, /* CA_ID 0x03 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC } },
{ .channels = 6, /* CA_ID 0x04 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 6, /* CA_ID 0x05 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 6, /* CA_ID 0x06 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 6, /* CA_ID 0x07 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 6, /* CA_ID 0x08 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
{ .channels = 6, /* CA_ID 0x09 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
{ .channels = 6, /* CA_ID 0x0A */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
{ .channels = 6, /* CA_ID 0x0B */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
{ .channels = 8, /* CA_ID 0x0C */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 8, /* CA_ID 0x0D */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 8, /* CA_ID 0x0E */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 8, /* CA_ID 0x0F */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 8, /* CA_ID 0x10 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
{ .channels = 8, /* CA_ID 0x11 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
{ .channels = 8, /* CA_ID 0x12 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
{ .channels = 8, /* CA_ID 0x13 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
{ .channels = 8, /* CA_ID 0x14 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x15 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x16 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x17 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x18 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x19 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1A */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1B */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1C */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1D */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1E */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1F */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ }
};
/*
* hdmi_codec_channel_alloc: speaker configuration available for CEA
*
* This is an ordered list that must match with hdmi_codec_8ch_chmaps struct
* The preceding ones have better chances to be selected by
* hdmi_codec_get_ch_alloc_table_idx().
*/
static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
{ .ca_id = 0x00, .n_ch = 2,
.mask = FL | FR},
/* 2.1 */
{ .ca_id = 0x01, .n_ch = 4,
.mask = FL | FR | LFE},
/* Dolby Surround */
{ .ca_id = 0x02, .n_ch = 4,
.mask = FL | FR | FC },
/* surround51 */
{ .ca_id = 0x0b, .n_ch = 6,
.mask = FL | FR | LFE | FC | RL | RR},
/* surround40 */
{ .ca_id = 0x08, .n_ch = 6,
.mask = FL | FR | RL | RR },
/* surround41 */
{ .ca_id = 0x09, .n_ch = 6,
.mask = FL | FR | LFE | RL | RR },
/* surround50 */
{ .ca_id = 0x0a, .n_ch = 6,
.mask = FL | FR | FC | RL | RR },
/* 6.1 */
{ .ca_id = 0x0f, .n_ch = 8,
.mask = FL | FR | LFE | FC | RL | RR | RC },
/* surround71 */
{ .ca_id = 0x13, .n_ch = 8,
.mask = FL | FR | LFE | FC | RL | RR | RLC | RRC },
/* others */
{ .ca_id = 0x03, .n_ch = 8,
.mask = FL | FR | LFE | FC },
{ .ca_id = 0x04, .n_ch = 8,
.mask = FL | FR | RC},
{ .ca_id = 0x05, .n_ch = 8,
.mask = FL | FR | LFE | RC },
{ .ca_id = 0x06, .n_ch = 8,
.mask = FL | FR | FC | RC },
{ .ca_id = 0x07, .n_ch = 8,
.mask = FL | FR | LFE | FC | RC },
{ .ca_id = 0x0c, .n_ch = 8,
.mask = FL | FR | RC | RL | RR },
{ .ca_id = 0x0d, .n_ch = 8,
.mask = FL | FR | LFE | RL | RR | RC },
{ .ca_id = 0x0e, .n_ch = 8,
.mask = FL | FR | FC | RL | RR | RC },
{ .ca_id = 0x10, .n_ch = 8,
.mask = FL | FR | RL | RR | RLC | RRC },
{ .ca_id = 0x11, .n_ch = 8,
.mask = FL | FR | LFE | RL | RR | RLC | RRC },
{ .ca_id = 0x12, .n_ch = 8,
.mask = FL | FR | FC | RL | RR | RLC | RRC },
{ .ca_id = 0x14, .n_ch = 8,
.mask = FL | FR | FLC | FRC },
{ .ca_id = 0x15, .n_ch = 8,
.mask = FL | FR | LFE | FLC | FRC },
{ .ca_id = 0x16, .n_ch = 8,
.mask = FL | FR | FC | FLC | FRC },
{ .ca_id = 0x17, .n_ch = 8,
.mask = FL | FR | LFE | FC | FLC | FRC },
{ .ca_id = 0x18, .n_ch = 8,
.mask = FL | FR | RC | FLC | FRC },
{ .ca_id = 0x19, .n_ch = 8,
.mask = FL | FR | LFE | RC | FLC | FRC },
{ .ca_id = 0x1a, .n_ch = 8,
.mask = FL | FR | RC | FC | FLC | FRC },
{ .ca_id = 0x1b, .n_ch = 8,
.mask = FL | FR | LFE | RC | FC | FLC | FRC },
{ .ca_id = 0x1c, .n_ch = 8,
.mask = FL | FR | RL | RR | FLC | FRC },
{ .ca_id = 0x1d, .n_ch = 8,
.mask = FL | FR | LFE | RL | RR | FLC | FRC },
{ .ca_id = 0x1e, .n_ch = 8,
.mask = FL | FR | FC | RL | RR | FLC | FRC },
{ .ca_id = 0x1f, .n_ch = 8,
.mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
};
struct hdmi_codec_priv { struct hdmi_codec_priv {
struct hdmi_codec_pdata hcd; struct hdmi_codec_pdata hcd;
struct snd_soc_dai_driver *daidrv; struct snd_soc_dai_driver *daidrv;
...@@ -41,6 +295,8 @@ struct hdmi_codec_priv { ...@@ -41,6 +295,8 @@ struct hdmi_codec_priv {
struct snd_pcm_substream *current_stream; struct snd_pcm_substream *current_stream;
struct snd_pcm_hw_constraint_list ratec; struct snd_pcm_hw_constraint_list ratec;
uint8_t eld[MAX_ELD_BYTES]; uint8_t eld[MAX_ELD_BYTES];
struct snd_pcm_chmap *chmap_info;
unsigned int chmap_idx;
}; };
static const struct snd_soc_dapm_widget hdmi_widgets[] = { static const struct snd_soc_dapm_widget hdmi_widgets[] = {
...@@ -79,6 +335,83 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, ...@@ -79,6 +335,83 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
return 0; return 0;
} }
static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
{
int i;
const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
[0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
[4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
};
unsigned long spk_mask = 0;
for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) {
if (spk_alloc & (1 << i))
spk_mask |= hdmi_codec_eld_spk_alloc_bits[i];
}
return spk_mask;
}
void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp)
{
u8 spk_alloc;
unsigned long spk_mask;
spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
/* Detect if only stereo supported, else return 8 channels mappings */
if ((spk_mask & ~(FL | FR)) && hcp->chmap_info->max_channels > 2)
hcp->chmap_info->chmap = hdmi_codec_8ch_chmaps;
else
hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
}
static int hdmi_codec_get_ch_alloc_table_idx(struct hdmi_codec_priv *hcp,
unsigned char channels)
{
int i;
u8 spk_alloc;
unsigned long spk_mask;
const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc;
spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) {
/* If spk_alloc == 0, HDMI is unplugged return stereo config*/
if (!spk_alloc && cap->ca_id == 0)
return i;
if (cap->n_ch != channels)
continue;
if (!(cap->mask == (spk_mask & cap->mask)))
continue;
return i;
}
return -EINVAL;
}
static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
unsigned const char *map;
unsigned int i;
struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
struct hdmi_codec_priv *hcp = info->private_data;
map = info->chmap[hcp->chmap_idx].map;
for (i = 0; i < info->max_channels; i++) {
if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN)
ucontrol->value.integer.value[i] = 0;
else
ucontrol->value.integer.value[i] = map[i];
}
return 0;
}
static const struct snd_kcontrol_new hdmi_controls[] = { static const struct snd_kcontrol_new hdmi_controls[] = {
{ {
.access = SNDRV_CTL_ELEM_ACCESS_READ | .access = SNDRV_CTL_ELEM_ACCESS_READ |
...@@ -140,6 +473,8 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream, ...@@ -140,6 +473,8 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
if (ret) if (ret)
return ret; return ret;
} }
/* Select chmap supported */
hdmi_codec_eld_chmap(hcp);
} }
return 0; return 0;
} }
...@@ -153,6 +488,7 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream, ...@@ -153,6 +488,7 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
WARN_ON(hcp->current_stream != substream); WARN_ON(hcp->current_stream != substream);
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data); hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
mutex_lock(&hcp->current_stream_lock); mutex_lock(&hcp->current_stream_lock);
...@@ -173,7 +509,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, ...@@ -173,7 +509,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
.dig_subframe = { 0 }, .dig_subframe = { 0 },
} }
}; };
int ret; int ret, idx;
dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
params_width(params), params_rate(params), params_width(params), params_rate(params),
...@@ -200,6 +536,17 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, ...@@ -200,6 +536,17 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
/* Select a channel allocation that matches with ELD and pcm channels */
idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels);
if (idx < 0) {
dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
idx);
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
return idx;
}
hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
hp.sample_width = params_width(params); hp.sample_width = params_width(params);
hp.sample_rate = params_rate(params); hp.sample_rate = params_rate(params);
hp.channels = params_channels(params); hp.channels = params_channels(params);
...@@ -328,6 +675,32 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = { ...@@ -328,6 +675,32 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = {
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai)
{
struct snd_soc_dai_driver *drv = dai->driver;
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
int ret;
dev_dbg(dai->dev, "%s()\n", __func__);
ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
NULL, drv->playback.channels_max, 0,
&hcp->chmap_info);
if (ret < 0)
return ret;
/* override handlers */
hcp->chmap_info->private_data = hcp;
hcp->chmap_info->kctl->get = hdmi_codec_chmap_ctl_get;
/* default chmap supported is stereo */
hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
return 0;
}
static struct snd_soc_dai_driver hdmi_i2s_dai = { static struct snd_soc_dai_driver hdmi_i2s_dai = {
.id = DAI_ID_I2S, .id = DAI_ID_I2S,
.playback = { .playback = {
...@@ -339,6 +712,7 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = { ...@@ -339,6 +712,7 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = {
.sig_bits = 24, .sig_bits = 24,
}, },
.ops = &hdmi_dai_ops, .ops = &hdmi_dai_ops,
.pcm_new = hdmi_codec_pcm_new,
}; };
static const struct snd_soc_dai_driver hdmi_spdif_dai = { static const struct snd_soc_dai_driver hdmi_spdif_dai = {
...@@ -351,6 +725,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = { ...@@ -351,6 +725,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
.formats = SPDIF_FORMATS, .formats = SPDIF_FORMATS,
}, },
.ops = &hdmi_dai_ops, .ops = &hdmi_dai_ops,
.pcm_new = hdmi_codec_pcm_new,
}; };
static char hdmi_dai_name[][DAI_NAME_SIZE] = { static char hdmi_dai_name[][DAI_NAME_SIZE] = {
...@@ -420,6 +795,7 @@ static int hdmi_codec_probe(struct platform_device *pdev) ...@@ -420,6 +795,7 @@ static int hdmi_codec_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
hd = NULL; hd = NULL;
mutex_lock(&hdmi_mutex);
list_for_each(pos, &hdmi_device_list) { list_for_each(pos, &hdmi_device_list) {
struct hdmi_device *tmp = pos_to_hdmi_device(pos); struct hdmi_device *tmp = pos_to_hdmi_device(pos);
...@@ -431,13 +807,16 @@ static int hdmi_codec_probe(struct platform_device *pdev) ...@@ -431,13 +807,16 @@ static int hdmi_codec_probe(struct platform_device *pdev)
if (!hd) { if (!hd) {
hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL); hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL);
if (!hd) if (!hd) {
mutex_unlock(&hdmi_mutex);
return -ENOMEM; return -ENOMEM;
}
hd->dev = dev->parent; hd->dev = dev->parent;
list_add_tail(&hd->list, &hdmi_device_list); list_add_tail(&hd->list, &hdmi_device_list);
} }
mutex_unlock(&hdmi_mutex);
if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) { if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) {
dev_err(dev, "too many hdmi codec are deteced\n"); dev_err(dev, "too many hdmi codec are deteced\n");
...@@ -479,7 +858,25 @@ static int hdmi_codec_probe(struct platform_device *pdev) ...@@ -479,7 +858,25 @@ static int hdmi_codec_probe(struct platform_device *pdev)
static int hdmi_codec_remove(struct platform_device *pdev) static int hdmi_codec_remove(struct platform_device *pdev)
{ {
snd_soc_unregister_codec(&pdev->dev); struct device *dev = &pdev->dev;
struct list_head *pos;
struct hdmi_codec_priv *hcp;
mutex_lock(&hdmi_mutex);
list_for_each(pos, &hdmi_device_list) {
struct hdmi_device *tmp = pos_to_hdmi_device(pos);
if (tmp->dev == dev->parent) {
list_del(pos);
break;
}
}
mutex_unlock(&hdmi_mutex);
hcp = dev_get_drvdata(dev);
kfree(hcp->chmap_info);
snd_soc_unregister_codec(dev);
return 0; return 0;
} }
......
...@@ -2456,7 +2456,7 @@ static int max98090_probe(struct snd_soc_codec *codec) ...@@ -2456,7 +2456,7 @@ static int max98090_probe(struct snd_soc_codec *codec)
if (err) { if (err) {
micbias = M98090_MBVSEL_2V8; micbias = M98090_MBVSEL_2V8;
dev_info(codec->dev, "use default 2.8v micbias\n"); dev_info(codec->dev, "use default 2.8v micbias\n");
} else if (micbias < M98090_MBVSEL_2V2 || micbias > M98090_MBVSEL_2V8) { } else if (micbias > M98090_MBVSEL_2V8) {
dev_err(codec->dev, "micbias out of range 0x%x\n", micbias); dev_err(codec->dev, "micbias out of range 0x%x\n", micbias);
micbias = M98090_MBVSEL_2V8; micbias = M98090_MBVSEL_2V8;
} }
......
...@@ -309,7 +309,6 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai, ...@@ -309,7 +309,6 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
struct snd_soc_codec *codec = codec_dai->codec; struct snd_soc_codec *codec = codec_dai->codec;
struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec); struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
u8 iface1A = 0, iface1B = 0; u8 iface1A = 0, iface1B = 0;
int ret;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM: case SND_SOC_DAIFMT_CBM_CFM:
...@@ -346,8 +345,8 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai, ...@@ -346,8 +345,8 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL; return -EINVAL;
} }
ret = regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A); regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
ret = regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B); regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B);
return 0; return 0;
} }
......
此差异已折叠。
/*
* NAU85L40 ALSA SoC audio driver
*
* Copyright 2016 Nuvoton Technology Corp.
* Author: John Hsu <KCHSU0@nuvoton.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __NAU8540_H__
#define __NAU8540_H__
#define NAU8540_REG_SW_RESET 0x00
#define NAU8540_REG_POWER_MANAGEMENT 0x01
#define NAU8540_REG_CLOCK_CTRL 0x02
#define NAU8540_REG_CLOCK_SRC 0x03
#define NAU8540_REG_FLL1 0x04
#define NAU8540_REG_FLL2 0x05
#define NAU8540_REG_FLL3 0x06
#define NAU8540_REG_FLL4 0x07
#define NAU8540_REG_FLL5 0x08
#define NAU8540_REG_FLL6 0x09
#define NAU8540_REG_FLL_VCO_RSV 0x0A
#define NAU8540_REG_PCM_CTRL0 0x10
#define NAU8540_REG_PCM_CTRL1 0x11
#define NAU8540_REG_PCM_CTRL2 0x12
#define NAU8540_REG_PCM_CTRL3 0x13
#define NAU8540_REG_PCM_CTRL4 0x14
#define NAU8540_REG_ALC_CONTROL_1 0x20
#define NAU8540_REG_ALC_CONTROL_2 0x21
#define NAU8540_REG_ALC_CONTROL_3 0x22
#define NAU8540_REG_ALC_CONTROL_4 0x23
#define NAU8540_REG_ALC_CONTROL_5 0x24
#define NAU8540_REG_ALC_GAIN_CH12 0x2D
#define NAU8540_REG_ALC_GAIN_CH34 0x2E
#define NAU8540_REG_ALC_STATUS 0x2F
#define NAU8540_REG_NOTCH_FIL1_CH1 0x30
#define NAU8540_REG_NOTCH_FIL2_CH1 0x31
#define NAU8540_REG_NOTCH_FIL1_CH2 0x32
#define NAU8540_REG_NOTCH_FIL2_CH2 0x33
#define NAU8540_REG_NOTCH_FIL1_CH3 0x34
#define NAU8540_REG_NOTCH_FIL2_CH3 0x35
#define NAU8540_REG_NOTCH_FIL1_CH4 0x36
#define NAU8540_REG_NOTCH_FIL2_CH4 0x37
#define NAU8540_REG_HPF_FILTER_CH12 0x38
#define NAU8540_REG_HPF_FILTER_CH34 0x39
#define NAU8540_REG_ADC_SAMPLE_RATE 0x3A
#define NAU8540_REG_DIGITAL_GAIN_CH1 0x40
#define NAU8540_REG_DIGITAL_GAIN_CH2 0x41
#define NAU8540_REG_DIGITAL_GAIN_CH3 0x42
#define NAU8540_REG_DIGITAL_GAIN_CH4 0x43
#define NAU8540_REG_DIGITAL_MUX 0x44
#define NAU8540_REG_P2P_CH1 0x48
#define NAU8540_REG_P2P_CH2 0x49
#define NAU8540_REG_P2P_CH3 0x4A
#define NAU8540_REG_P2P_CH4 0x4B
#define NAU8540_REG_PEAK_CH1 0x4C
#define NAU8540_REG_PEAK_CH2 0x4D
#define NAU8540_REG_PEAK_CH3 0x4E
#define NAU8540_REG_PEAK_CH4 0x4F
#define NAU8540_REG_GPIO_CTRL 0x50
#define NAU8540_REG_MISC_CTRL 0x51
#define NAU8540_REG_I2C_CTRL 0x52
#define NAU8540_REG_I2C_DEVICE_ID 0x58
#define NAU8540_REG_RST 0x5A
#define NAU8540_REG_VMID_CTRL 0x60
#define NAU8540_REG_MUTE 0x61
#define NAU8540_REG_ANALOG_ADC1 0x64
#define NAU8540_REG_ANALOG_ADC2 0x65
#define NAU8540_REG_ANALOG_PWR 0x66
#define NAU8540_REG_MIC_BIAS 0x67
#define NAU8540_REG_REFERENCE 0x68
#define NAU8540_REG_FEPGA1 0x69
#define NAU8540_REG_FEPGA2 0x6A
#define NAU8540_REG_FEPGA3 0x6B
#define NAU8540_REG_FEPGA4 0x6C
#define NAU8540_REG_PWR 0x6D
#define NAU8540_REG_MAX NAU8540_REG_PWR
/* POWER_MANAGEMENT (0x01) */
#define NAU8540_ADC4_EN (0x1 << 3)
#define NAU8540_ADC3_EN (0x1 << 2)
#define NAU8540_ADC2_EN (0x1 << 1)
#define NAU8540_ADC1_EN 0x1
/* CLOCK_CTRL (0x02) */
#define NAU8540_CLK_ADC_EN (0x1 << 15)
#define NAU8540_CLK_I2S_EN (0x1 << 1)
/* CLOCK_SRC (0x03) */
#define NAU8540_CLK_SRC_SFT 15
#define NAU8540_CLK_SRC_MASK (1 << NAU8540_CLK_SRC_SFT)
#define NAU8540_CLK_SRC_VCO (1 << NAU8540_CLK_SRC_SFT)
#define NAU8540_CLK_SRC_MCLK (0 << NAU8540_CLK_SRC_SFT)
#define NAU8540_CLK_ADC_SRC_SFT 6
#define NAU8540_CLK_ADC_SRC_MASK (0x3 << NAU8540_CLK_ADC_SRC_SFT)
#define NAU8540_CLK_MCLK_SRC_MASK 0xf
/* FLL1 (0x04) */
#define NAU8540_FLL_RATIO_MASK 0x7f
/* FLL3 (0x06) */
#define NAU8540_FLL_CLK_SRC_SFT 10
#define NAU8540_FLL_CLK_SRC_MASK (0x3 << NAU8540_FLL_CLK_SRC_SFT)
#define NAU8540_FLL_CLK_SRC_MCLK (0 << NAU8540_FLL_CLK_SRC_SFT)
#define NAU8540_FLL_CLK_SRC_BLK (0x2 << NAU8540_FLL_CLK_SRC_SFT)
#define NAU8540_FLL_CLK_SRC_FS (0x3 << NAU8540_FLL_CLK_SRC_SFT)
#define NAU8540_FLL_INTEGER_MASK 0x3ff
/* FLL4 (0x07) */
#define NAU8540_FLL_REF_DIV_SFT 10
#define NAU8540_FLL_REF_DIV_MASK (0x3 << NAU8540_FLL_REF_DIV_SFT)
/* FLL5 (0x08) */
#define NAU8540_FLL_PDB_DAC_EN (0x1 << 15)
#define NAU8540_FLL_LOOP_FTR_EN (0x1 << 14)
#define NAU8540_FLL_CLK_SW_MASK (0x1 << 13)
#define NAU8540_FLL_CLK_SW_N2 (0x1 << 13)
#define NAU8540_FLL_CLK_SW_REF (0x0 << 13)
#define NAU8540_FLL_FTR_SW_MASK (0x1 << 12)
#define NAU8540_FLL_FTR_SW_ACCU (0x1 << 12)
#define NAU8540_FLL_FTR_SW_FILTER (0x0 << 12)
/* FLL6 (0x9) */
#define NAU8540_DCO_EN (0x1 << 15)
#define NAU8540_SDM_EN (0x1 << 14)
/* PCM_CTRL0 (0x10) */
#define NAU8540_I2S_BP_SFT 7
#define NAU8540_I2S_BP_INV (0x1 << NAU8540_I2S_BP_SFT)
#define NAU8540_I2S_PCMB_SFT 6
#define NAU8540_I2S_PCMB_EN (0x1 << NAU8540_I2S_PCMB_SFT)
#define NAU8540_I2S_DL_SFT 2
#define NAU8540_I2S_DL_MASK (0x3 << NAU8540_I2S_DL_SFT)
#define NAU8540_I2S_DL_16 (0 << NAU8540_I2S_DL_SFT)
#define NAU8540_I2S_DL_20 (0x1 << NAU8540_I2S_DL_SFT)
#define NAU8540_I2S_DL_24 (0x2 << NAU8540_I2S_DL_SFT)
#define NAU8540_I2S_DL_32 (0x3 << NAU8540_I2S_DL_SFT)
#define NAU8540_I2S_DF_MASK 0x3
#define NAU8540_I2S_DF_RIGTH 0
#define NAU8540_I2S_DF_LEFT 0x1
#define NAU8540_I2S_DF_I2S 0x2
#define NAU8540_I2S_DF_PCM_AB 0x3
/* PCM_CTRL1 (0x11) */
#define NAU8540_I2S_LRC_DIV_SFT 12
#define NAU8540_I2S_LRC_DIV_MASK (0x3 << NAU8540_I2S_LRC_DIV_SFT)
#define NAU8540_I2S_DO12_OE (0x1 << 4)
#define NAU8540_I2S_MS_SFT 3
#define NAU8540_I2S_MS_MASK (0x1 << NAU8540_I2S_MS_SFT)
#define NAU8540_I2S_MS_MASTER (0x1 << NAU8540_I2S_MS_SFT)
#define NAU8540_I2S_MS_SLAVE (0x0 << NAU8540_I2S_MS_SFT)
#define NAU8540_I2S_BLK_DIV_MASK 0x7
/* PCM_CTRL1 (0x12) */
#define NAU8540_I2S_DO34_OE (0x1 << 11)
#define NAU8540_I2S_TSLOT_L_MASK 0x3ff
/* PCM_CTRL4 (0x14) */
#define NAU8540_TDM_MODE (0x1 << 15)
#define NAU8540_TDM_OFFSET_EN (0x1 << 14)
#define NAU8540_TDM_TX_MASK 0xf
/* ADC_SAMPLE_RATE (0x3A) */
#define NAU8540_ADC_OSR_MASK 0x3
#define NAU8540_ADC_OSR_256 0x3
#define NAU8540_ADC_OSR_128 0x2
#define NAU8540_ADC_OSR_64 0x1
#define NAU8540_ADC_OSR_32 0x0
/* VMID_CTRL (0x60) */
#define NAU8540_VMID_EN (1 << 6)
#define NAU8540_VMID_SEL_SFT 4
#define NAU8540_VMID_SEL_MASK (0x3 << NAU8540_VMID_SEL_SFT)
/* MIC_BIAS (0x67) */
#define NAU8540_PU_PRE (0x1 << 8)
/* REFERENCE (0x68) */
#define NAU8540_PRECHARGE_DIS (0x1 << 13)
#define NAU8540_GLOBAL_BIAS_EN (0x1 << 12)
/* System Clock Source */
enum {
NAU8540_CLK_DIS,
NAU8540_CLK_MCLK,
NAU8540_CLK_INTERNAL,
NAU8540_CLK_FLL_MCLK,
NAU8540_CLK_FLL_BLK,
NAU8540_CLK_FLL_FS,
};
struct nau8540 {
struct device *dev;
struct regmap *regmap;
};
struct nau8540_fll {
int mclk_src;
int ratio;
int fll_frac;
int fll_int;
int clk_ref_div;
};
struct nau8540_fll_attr {
unsigned int param;
unsigned int val;
};
/* over sampling rate */
struct nau8540_osr_attr {
unsigned int osr;
unsigned int clk_src;
};
#endif /* __NAU8540_H__ */
...@@ -1231,7 +1231,7 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream, ...@@ -1231,7 +1231,7 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
unsigned int val_len = 0, osr; unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
nau8825_sema_acquire(nau8825, 3 * HZ); nau8825_sema_acquire(nau8825, 3 * HZ);
...@@ -1261,6 +1261,24 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream, ...@@ -1261,6 +1261,24 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
osr_adc_sel[osr].clk_src << NAU8825_CLK_ADC_SRC_SFT); osr_adc_sel[osr].clk_src << NAU8825_CLK_ADC_SRC_SFT);
} }
/* make BCLK and LRC divde configuration if the codec as master. */
regmap_read(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, &ctrl_val);
if (ctrl_val & NAU8825_I2S_MS_MASTER) {
/* get the bclk and fs ratio */
bclk_fs = snd_soc_params_to_bclk(params) / params_rate(params);
if (bclk_fs <= 32)
bclk_div = 2;
else if (bclk_fs <= 64)
bclk_div = 1;
else if (bclk_fs <= 128)
bclk_div = 0;
else
return -EINVAL;
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
NAU8825_I2S_LRC_DIV_MASK | NAU8825_I2S_BLK_DIV_MASK,
((bclk_div + 1) << NAU8825_I2S_LRC_DIV_SFT) | bclk_div);
}
switch (params_width(params)) { switch (params_width(params)) {
case 16: case 16:
val_len |= NAU8825_I2S_DL_16; val_len |= NAU8825_I2S_DL_16;
......
...@@ -402,10 +402,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, ...@@ -402,10 +402,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
u32 val, mask, shift, reg; u32 val, mask, shift, reg;
unsigned int rate, fmt, ratio, max_ratio; unsigned int rate, fmt, ratio, max_ratio;
int i, min_frame_size; int i, min_frame_size;
snd_pcm_format_t format;
rate = params_rate(params); rate = params_rate(params);
format = params_format(params);
ratio = pcm3168a->sysclk / rate; ratio = pcm3168a->sysclk / rate;
......
...@@ -1163,6 +1163,13 @@ static const struct dmi_system_id force_combo_jack_table[] = { ...@@ -1163,6 +1163,13 @@ static const struct dmi_system_id force_combo_jack_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Broxton P") DMI_MATCH(DMI_PRODUCT_NAME, "Broxton P")
} }
}, },
{
.ident = "Intel Gemini Lake",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp"),
DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake")
}
},
{ } { }
}; };
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/pm_qos.h> #include <linux/pm_qos.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
......
...@@ -995,7 +995,7 @@ static int rt5640_hp_event(struct snd_soc_dapm_widget *w, ...@@ -995,7 +995,7 @@ static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_PRE_PMD:
rt5640->hp_mute = 1; rt5640->hp_mute = 1;
usleep_range(70000, 75000); msleep(70);
break; break;
default: default:
...@@ -1059,7 +1059,7 @@ static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w, ...@@ -1059,7 +1059,7 @@ static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
switch (event) { switch (event) {
case SND_SOC_DAPM_POST_PMU: case SND_SOC_DAPM_POST_PMU:
if (!rt5640->hp_mute) if (!rt5640->hp_mute)
usleep_range(80000, 85000); msleep(80);
break; break;
...@@ -1227,6 +1227,10 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { ...@@ -1227,6 +1227,10 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
RT5640_PWR_DAC_L1_BIT, 0, NULL, 0), RT5640_PWR_DAC_L1_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5640_PWR_DIG1, SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_R1_BIT, 0, NULL, 0), RT5640_PWR_DAC_R1_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_L2_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_R2_BIT, 0, NULL, 0),
/* SPK/OUT Mixer */ /* SPK/OUT Mixer */
SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT, SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT,
0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)), 0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)),
...@@ -1322,10 +1326,6 @@ static const struct snd_soc_dapm_widget rt5640_specific_dapm_widgets[] = { ...@@ -1322,10 +1326,6 @@ static const struct snd_soc_dapm_widget rt5640_specific_dapm_widgets[] = {
rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
RT5640_PWR_MA_BIT, 0, NULL, 0), RT5640_PWR_MA_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_L2_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_R2_BIT, 0, NULL, 0),
SND_SOC_DAPM_OUTPUT("MONOP"), SND_SOC_DAPM_OUTPUT("MONOP"),
SND_SOC_DAPM_OUTPUT("MONON"), SND_SOC_DAPM_OUTPUT("MONON"),
...@@ -2313,6 +2313,7 @@ MODULE_DEVICE_TABLE(of, rt5640_of_match); ...@@ -2313,6 +2313,7 @@ MODULE_DEVICE_TABLE(of, rt5640_of_match);
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static const struct acpi_device_id rt5640_acpi_match[] = { static const struct acpi_device_id rt5640_acpi_match[] = {
{ "INT33CA", 0 }, { "INT33CA", 0 },
{ "10EC3276", 0 },
{ "10EC5640", 0 }, { "10EC5640", 0 },
{ "10EC5642", 0 }, { "10EC5642", 0 },
{ "INTCCFFD", 0 }, { "INTCCFFD", 0 },
......
...@@ -3109,7 +3109,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert) ...@@ -3109,7 +3109,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
unsigned int val; unsigned int val;
if (jack_insert) { if (jack_insert) {
regmap_write(rt5645->regmap, RT5645_CHARGE_PUMP, 0x0006); regmap_write(rt5645->regmap, RT5645_CHARGE_PUMP, 0x0e06);
/* for jack type detect */ /* for jack type detect */
snd_soc_dapm_force_enable_pin(dapm, "LDO2"); snd_soc_dapm_force_enable_pin(dapm, "LDO2");
...@@ -3545,8 +3545,10 @@ MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); ...@@ -3545,8 +3545,10 @@ MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static const struct acpi_device_id rt5645_acpi_match[] = { static const struct acpi_device_id rt5645_acpi_match[] = {
{ "10EC5645", 0 }, { "10EC5645", 0 },
{ "10EC5648", 0 },
{ "10EC5650", 0 }, { "10EC5650", 0 },
{ "10EC5640", 0 }, { "10EC5640", 0 },
{ "10EC3270", 0 },
{}, {},
}; };
MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match);
...@@ -3658,8 +3660,14 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, ...@@ -3658,8 +3660,14 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
GPIOD_IN); GPIOD_IN);
if (IS_ERR(rt5645->gpiod_hp_det)) { if (IS_ERR(rt5645->gpiod_hp_det)) {
dev_err(&i2c->dev, "failed to initialize gpiod\n"); dev_info(&i2c->dev, "failed to initialize gpiod\n");
return PTR_ERR(rt5645->gpiod_hp_det); ret = PTR_ERR(rt5645->gpiod_hp_det);
/*
* Continue if optional gpiod is missing, bail for all other
* errors, including -EPROBE_DEFER
*/
if (ret != -ENOENT)
return ret;
} }
for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++) for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++)
......
...@@ -1150,28 +1150,28 @@ static const char * const rt5659_data_select[] = { ...@@ -1150,28 +1150,28 @@ static const char * const rt5659_data_select[] = {
"L/R", "R/L", "L/L", "R/R" "L/R", "R/L", "L/L", "R/R"
}; };
static const SOC_ENUM_SINGLE_DECL(rt5659_if1_01_adc_enum, static SOC_ENUM_SINGLE_DECL(rt5659_if1_01_adc_enum,
RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT01_SFT, rt5659_data_select); RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT01_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if1_23_adc_enum, static SOC_ENUM_SINGLE_DECL(rt5659_if1_23_adc_enum,
RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT23_SFT, rt5659_data_select); RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT23_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if1_45_adc_enum, static SOC_ENUM_SINGLE_DECL(rt5659_if1_45_adc_enum,
RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT45_SFT, rt5659_data_select); RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT45_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if1_67_adc_enum, static SOC_ENUM_SINGLE_DECL(rt5659_if1_67_adc_enum,
RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT67_SFT, rt5659_data_select); RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT67_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if2_dac_enum, static SOC_ENUM_SINGLE_DECL(rt5659_if2_dac_enum,
RT5659_DIG_INF23_DATA, RT5659_IF2_DAC_SEL_SFT, rt5659_data_select); RT5659_DIG_INF23_DATA, RT5659_IF2_DAC_SEL_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if2_adc_enum, static SOC_ENUM_SINGLE_DECL(rt5659_if2_adc_enum,
RT5659_DIG_INF23_DATA, RT5659_IF2_ADC_SEL_SFT, rt5659_data_select); RT5659_DIG_INF23_DATA, RT5659_IF2_ADC_SEL_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if3_dac_enum, static SOC_ENUM_SINGLE_DECL(rt5659_if3_dac_enum,
RT5659_DIG_INF23_DATA, RT5659_IF3_DAC_SEL_SFT, rt5659_data_select); RT5659_DIG_INF23_DATA, RT5659_IF3_DAC_SEL_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if3_adc_enum, static SOC_ENUM_SINGLE_DECL(rt5659_if3_adc_enum,
RT5659_DIG_INF23_DATA, RT5659_IF3_ADC_SEL_SFT, rt5659_data_select); RT5659_DIG_INF23_DATA, RT5659_IF3_ADC_SEL_SFT, rt5659_data_select);
static const struct snd_kcontrol_new rt5659_if1_01_adc_swap_mux = static const struct snd_kcontrol_new rt5659_if1_01_adc_swap_mux =
...@@ -1207,31 +1207,31 @@ static unsigned int rt5659_asrc_clk_map_values[] = { ...@@ -1207,31 +1207,31 @@ static unsigned int rt5659_asrc_clk_map_values[] = {
0, 1, 2, 3, 5, 6, 0, 1, 2, 3, 5, 6,
}; };
static const SOC_VALUE_ENUM_SINGLE_DECL( static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_da_sto_asrc_enum, RT5659_ASRC_2, RT5659_DA_STO_T_SFT, 0x7, rt5659_da_sto_asrc_enum, RT5659_ASRC_2, RT5659_DA_STO_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values); rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL( static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_da_monol_asrc_enum, RT5659_ASRC_2, RT5659_DA_MONO_L_T_SFT, 0x7, rt5659_da_monol_asrc_enum, RT5659_ASRC_2, RT5659_DA_MONO_L_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values); rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL( static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_da_monor_asrc_enum, RT5659_ASRC_2, RT5659_DA_MONO_R_T_SFT, 0x7, rt5659_da_monor_asrc_enum, RT5659_ASRC_2, RT5659_DA_MONO_R_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values); rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL( static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_ad_sto1_asrc_enum, RT5659_ASRC_2, RT5659_AD_STO1_T_SFT, 0x7, rt5659_ad_sto1_asrc_enum, RT5659_ASRC_2, RT5659_AD_STO1_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values); rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL( static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_ad_sto2_asrc_enum, RT5659_ASRC_3, RT5659_AD_STO2_T_SFT, 0x7, rt5659_ad_sto2_asrc_enum, RT5659_ASRC_3, RT5659_AD_STO2_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values); rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL( static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_ad_monol_asrc_enum, RT5659_ASRC_3, RT5659_AD_MONO_L_T_SFT, 0x7, rt5659_ad_monol_asrc_enum, RT5659_ASRC_3, RT5659_AD_MONO_L_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values); rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL( static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_ad_monor_asrc_enum, RT5659_ASRC_3, RT5659_AD_MONO_R_T_SFT, 0x7, rt5659_ad_monor_asrc_enum, RT5659_ASRC_3, RT5659_AD_MONO_R_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values); rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
...@@ -1930,14 +1930,14 @@ static const char * const rt5659_dac2_src[] = { ...@@ -1930,14 +1930,14 @@ static const char * const rt5659_dac2_src[] = {
"IF1 DAC2", "IF2 DAC", "IF3 DAC", "Mono ADC MIX" "IF1 DAC2", "IF2 DAC", "IF3 DAC", "Mono ADC MIX"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_dac_l2_enum, RT5659_DAC_CTRL, rt5659_dac_l2_enum, RT5659_DAC_CTRL,
RT5659_DAC_L2_SEL_SFT, rt5659_dac2_src); RT5659_DAC_L2_SEL_SFT, rt5659_dac2_src);
static const struct snd_kcontrol_new rt5659_dac_l2_mux = static const struct snd_kcontrol_new rt5659_dac_l2_mux =
SOC_DAPM_ENUM("DAC L2 Source", rt5659_dac_l2_enum); SOC_DAPM_ENUM("DAC L2 Source", rt5659_dac_l2_enum);
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_dac_r2_enum, RT5659_DAC_CTRL, rt5659_dac_r2_enum, RT5659_DAC_CTRL,
RT5659_DAC_R2_SEL_SFT, rt5659_dac2_src); RT5659_DAC_R2_SEL_SFT, rt5659_dac2_src);
...@@ -1951,7 +1951,7 @@ static const char * const rt5659_sto1_adc1_src[] = { ...@@ -1951,7 +1951,7 @@ static const char * const rt5659_sto1_adc1_src[] = {
"DAC MIX", "ADC" "DAC MIX", "ADC"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_sto1_adc1_enum, RT5659_STO1_ADC_MIXER, rt5659_sto1_adc1_enum, RT5659_STO1_ADC_MIXER,
RT5659_STO1_ADC1_SRC_SFT, rt5659_sto1_adc1_src); RT5659_STO1_ADC1_SRC_SFT, rt5659_sto1_adc1_src);
...@@ -1964,7 +1964,7 @@ static const char * const rt5659_sto1_adc_src[] = { ...@@ -1964,7 +1964,7 @@ static const char * const rt5659_sto1_adc_src[] = {
"ADC1", "ADC2" "ADC1", "ADC2"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_sto1_adc_enum, RT5659_STO1_ADC_MIXER, rt5659_sto1_adc_enum, RT5659_STO1_ADC_MIXER,
RT5659_STO1_ADC_SRC_SFT, rt5659_sto1_adc_src); RT5659_STO1_ADC_SRC_SFT, rt5659_sto1_adc_src);
...@@ -1977,7 +1977,7 @@ static const char * const rt5659_sto1_adc2_src[] = { ...@@ -1977,7 +1977,7 @@ static const char * const rt5659_sto1_adc2_src[] = {
"DAC MIX", "DMIC" "DAC MIX", "DMIC"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_sto1_adc2_enum, RT5659_STO1_ADC_MIXER, rt5659_sto1_adc2_enum, RT5659_STO1_ADC_MIXER,
RT5659_STO1_ADC2_SRC_SFT, rt5659_sto1_adc2_src); RT5659_STO1_ADC2_SRC_SFT, rt5659_sto1_adc2_src);
...@@ -1990,7 +1990,7 @@ static const char * const rt5659_sto1_dmic_src[] = { ...@@ -1990,7 +1990,7 @@ static const char * const rt5659_sto1_dmic_src[] = {
"DMIC1", "DMIC2" "DMIC1", "DMIC2"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_sto1_dmic_enum, RT5659_STO1_ADC_MIXER, rt5659_sto1_dmic_enum, RT5659_STO1_ADC_MIXER,
RT5659_STO1_DMIC_SRC_SFT, rt5659_sto1_dmic_src); RT5659_STO1_DMIC_SRC_SFT, rt5659_sto1_dmic_src);
...@@ -2004,7 +2004,7 @@ static const char * const rt5659_mono_adc_l2_src[] = { ...@@ -2004,7 +2004,7 @@ static const char * const rt5659_mono_adc_l2_src[] = {
"Mono DAC MIXL", "DMIC" "Mono DAC MIXL", "DMIC"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adc_l2_enum, RT5659_MONO_ADC_MIXER, rt5659_mono_adc_l2_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_L2_SRC_SFT, rt5659_mono_adc_l2_src); RT5659_MONO_ADC_L2_SRC_SFT, rt5659_mono_adc_l2_src);
...@@ -2018,7 +2018,7 @@ static const char * const rt5659_mono_adc_l1_src[] = { ...@@ -2018,7 +2018,7 @@ static const char * const rt5659_mono_adc_l1_src[] = {
"Mono DAC MIXL", "ADC" "Mono DAC MIXL", "ADC"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adc_l1_enum, RT5659_MONO_ADC_MIXER, rt5659_mono_adc_l1_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_L1_SRC_SFT, rt5659_mono_adc_l1_src); RT5659_MONO_ADC_L1_SRC_SFT, rt5659_mono_adc_l1_src);
...@@ -2031,14 +2031,14 @@ static const char * const rt5659_mono_adc_src[] = { ...@@ -2031,14 +2031,14 @@ static const char * const rt5659_mono_adc_src[] = {
"ADC1 L", "ADC1 R", "ADC2 L", "ADC2 R" "ADC1 L", "ADC1 R", "ADC2 L", "ADC2 R"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adc_l_enum, RT5659_MONO_ADC_MIXER, rt5659_mono_adc_l_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_L_SRC_SFT, rt5659_mono_adc_src); RT5659_MONO_ADC_L_SRC_SFT, rt5659_mono_adc_src);
static const struct snd_kcontrol_new rt5659_mono_adc_l_mux = static const struct snd_kcontrol_new rt5659_mono_adc_l_mux =
SOC_DAPM_ENUM("Mono ADC L Source", rt5659_mono_adc_l_enum); SOC_DAPM_ENUM("Mono ADC L Source", rt5659_mono_adc_l_enum);
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adcr_enum, RT5659_MONO_ADC_MIXER, rt5659_mono_adcr_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_R_SRC_SFT, rt5659_mono_adc_src); RT5659_MONO_ADC_R_SRC_SFT, rt5659_mono_adc_src);
...@@ -2051,7 +2051,7 @@ static const char * const rt5659_mono_dmic_l_src[] = { ...@@ -2051,7 +2051,7 @@ static const char * const rt5659_mono_dmic_l_src[] = {
"DMIC1 L", "DMIC2 L" "DMIC1 L", "DMIC2 L"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_mono_dmic_l_enum, RT5659_MONO_ADC_MIXER, rt5659_mono_dmic_l_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_DMIC_L_SRC_SFT, rt5659_mono_dmic_l_src); RT5659_MONO_DMIC_L_SRC_SFT, rt5659_mono_dmic_l_src);
...@@ -2064,7 +2064,7 @@ static const char * const rt5659_mono_adc_r2_src[] = { ...@@ -2064,7 +2064,7 @@ static const char * const rt5659_mono_adc_r2_src[] = {
"Mono DAC MIXR", "DMIC" "Mono DAC MIXR", "DMIC"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adc_r2_enum, RT5659_MONO_ADC_MIXER, rt5659_mono_adc_r2_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_R2_SRC_SFT, rt5659_mono_adc_r2_src); RT5659_MONO_ADC_R2_SRC_SFT, rt5659_mono_adc_r2_src);
...@@ -2077,7 +2077,7 @@ static const char * const rt5659_mono_adc_r1_src[] = { ...@@ -2077,7 +2077,7 @@ static const char * const rt5659_mono_adc_r1_src[] = {
"Mono DAC MIXR", "ADC" "Mono DAC MIXR", "ADC"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adc_r1_enum, RT5659_MONO_ADC_MIXER, rt5659_mono_adc_r1_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_R1_SRC_SFT, rt5659_mono_adc_r1_src); RT5659_MONO_ADC_R1_SRC_SFT, rt5659_mono_adc_r1_src);
...@@ -2090,7 +2090,7 @@ static const char * const rt5659_mono_dmic_r_src[] = { ...@@ -2090,7 +2090,7 @@ static const char * const rt5659_mono_dmic_r_src[] = {
"DMIC1 R", "DMIC2 R" "DMIC1 R", "DMIC2 R"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_mono_dmic_r_enum, RT5659_MONO_ADC_MIXER, rt5659_mono_dmic_r_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_DMIC_R_SRC_SFT, rt5659_mono_dmic_r_src); RT5659_MONO_DMIC_R_SRC_SFT, rt5659_mono_dmic_r_src);
...@@ -2104,14 +2104,14 @@ static const char * const rt5659_dac1_src[] = { ...@@ -2104,14 +2104,14 @@ static const char * const rt5659_dac1_src[] = {
"IF1 DAC1", "IF2 DAC", "IF3 DAC" "IF1 DAC1", "IF2 DAC", "IF3 DAC"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_dac_r1_enum, RT5659_AD_DA_MIXER, rt5659_dac_r1_enum, RT5659_AD_DA_MIXER,
RT5659_DAC1_R_SEL_SFT, rt5659_dac1_src); RT5659_DAC1_R_SEL_SFT, rt5659_dac1_src);
static const struct snd_kcontrol_new rt5659_dac_r1_mux = static const struct snd_kcontrol_new rt5659_dac_r1_mux =
SOC_DAPM_ENUM("DAC R1 Source", rt5659_dac_r1_enum); SOC_DAPM_ENUM("DAC R1 Source", rt5659_dac_r1_enum);
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_dac_l1_enum, RT5659_AD_DA_MIXER, rt5659_dac_l1_enum, RT5659_AD_DA_MIXER,
RT5659_DAC1_L_SEL_SFT, rt5659_dac1_src); RT5659_DAC1_L_SEL_SFT, rt5659_dac1_src);
...@@ -2124,14 +2124,14 @@ static const char * const rt5659_dig_dac_mix_src[] = { ...@@ -2124,14 +2124,14 @@ static const char * const rt5659_dig_dac_mix_src[] = {
"Stereo DAC Mixer", "Mono DAC Mixer" "Stereo DAC Mixer", "Mono DAC Mixer"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_dig_dac_mixl_enum, RT5659_DIG_MIXER, rt5659_dig_dac_mixl_enum, RT5659_DIG_MIXER,
RT5659_DAC_MIX_L_SFT, rt5659_dig_dac_mix_src); RT5659_DAC_MIX_L_SFT, rt5659_dig_dac_mix_src);
static const struct snd_kcontrol_new rt5659_dig_dac_mixl_mux = static const struct snd_kcontrol_new rt5659_dig_dac_mixl_mux =
SOC_DAPM_ENUM("DAC Digital Mixer L Source", rt5659_dig_dac_mixl_enum); SOC_DAPM_ENUM("DAC Digital Mixer L Source", rt5659_dig_dac_mixl_enum);
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_dig_dac_mixr_enum, RT5659_DIG_MIXER, rt5659_dig_dac_mixr_enum, RT5659_DIG_MIXER,
RT5659_DAC_MIX_R_SFT, rt5659_dig_dac_mix_src); RT5659_DAC_MIX_R_SFT, rt5659_dig_dac_mix_src);
...@@ -2144,14 +2144,14 @@ static const char * const rt5659_alg_dac1_src[] = { ...@@ -2144,14 +2144,14 @@ static const char * const rt5659_alg_dac1_src[] = {
"DAC", "Stereo DAC Mixer" "DAC", "Stereo DAC Mixer"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_alg_dac_l1_enum, RT5659_A_DAC_MUX, rt5659_alg_dac_l1_enum, RT5659_A_DAC_MUX,
RT5659_A_DACL1_SFT, rt5659_alg_dac1_src); RT5659_A_DACL1_SFT, rt5659_alg_dac1_src);
static const struct snd_kcontrol_new rt5659_alg_dac_l1_mux = static const struct snd_kcontrol_new rt5659_alg_dac_l1_mux =
SOC_DAPM_ENUM("Analog DACL1 Source", rt5659_alg_dac_l1_enum); SOC_DAPM_ENUM("Analog DACL1 Source", rt5659_alg_dac_l1_enum);
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_alg_dac_r1_enum, RT5659_A_DAC_MUX, rt5659_alg_dac_r1_enum, RT5659_A_DAC_MUX,
RT5659_A_DACR1_SFT, rt5659_alg_dac1_src); RT5659_A_DACR1_SFT, rt5659_alg_dac1_src);
...@@ -2164,14 +2164,14 @@ static const char * const rt5659_alg_dac2_src[] = { ...@@ -2164,14 +2164,14 @@ static const char * const rt5659_alg_dac2_src[] = {
"Stereo DAC Mixer", "Mono DAC Mixer" "Stereo DAC Mixer", "Mono DAC Mixer"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_alg_dac_l2_enum, RT5659_A_DAC_MUX, rt5659_alg_dac_l2_enum, RT5659_A_DAC_MUX,
RT5659_A_DACL2_SFT, rt5659_alg_dac2_src); RT5659_A_DACL2_SFT, rt5659_alg_dac2_src);
static const struct snd_kcontrol_new rt5659_alg_dac_l2_mux = static const struct snd_kcontrol_new rt5659_alg_dac_l2_mux =
SOC_DAPM_ENUM("Analog DAC L2 Source", rt5659_alg_dac_l2_enum); SOC_DAPM_ENUM("Analog DAC L2 Source", rt5659_alg_dac_l2_enum);
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_alg_dac_r2_enum, RT5659_A_DAC_MUX, rt5659_alg_dac_r2_enum, RT5659_A_DAC_MUX,
RT5659_A_DACR2_SFT, rt5659_alg_dac2_src); RT5659_A_DACR2_SFT, rt5659_alg_dac2_src);
...@@ -2184,7 +2184,7 @@ static const char * const rt5659_if2_adc_in_src[] = { ...@@ -2184,7 +2184,7 @@ static const char * const rt5659_if2_adc_in_src[] = {
"IF_ADC1", "IF_ADC2", "DAC_REF", "IF_ADC3" "IF_ADC1", "IF_ADC2", "DAC_REF", "IF_ADC3"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_if2_adc_in_enum, RT5659_DIG_INF23_DATA, rt5659_if2_adc_in_enum, RT5659_DIG_INF23_DATA,
RT5659_IF2_ADC_IN_SFT, rt5659_if2_adc_in_src); RT5659_IF2_ADC_IN_SFT, rt5659_if2_adc_in_src);
...@@ -2197,7 +2197,7 @@ static const char * const rt5659_if3_adc_in_src[] = { ...@@ -2197,7 +2197,7 @@ static const char * const rt5659_if3_adc_in_src[] = {
"IF_ADC1", "IF_ADC2", "DAC_REF", "Stereo2_ADC_L/R" "IF_ADC1", "IF_ADC2", "DAC_REF", "Stereo2_ADC_L/R"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_if3_adc_in_enum, RT5659_DIG_INF23_DATA, rt5659_if3_adc_in_enum, RT5659_DIG_INF23_DATA,
RT5659_IF3_ADC_IN_SFT, rt5659_if3_adc_in_src); RT5659_IF3_ADC_IN_SFT, rt5659_if3_adc_in_src);
...@@ -2210,14 +2210,14 @@ static const char * const rt5659_pdm_src[] = { ...@@ -2210,14 +2210,14 @@ static const char * const rt5659_pdm_src[] = {
"Mono DAC", "Stereo DAC" "Mono DAC", "Stereo DAC"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_pdm_l_enum, RT5659_PDM_OUT_CTRL, rt5659_pdm_l_enum, RT5659_PDM_OUT_CTRL,
RT5659_PDM1_L_SFT, rt5659_pdm_src); RT5659_PDM1_L_SFT, rt5659_pdm_src);
static const struct snd_kcontrol_new rt5659_pdm_l_mux = static const struct snd_kcontrol_new rt5659_pdm_l_mux =
SOC_DAPM_ENUM("PDM L Source", rt5659_pdm_l_enum); SOC_DAPM_ENUM("PDM L Source", rt5659_pdm_l_enum);
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_pdm_r_enum, RT5659_PDM_OUT_CTRL, rt5659_pdm_r_enum, RT5659_PDM_OUT_CTRL,
RT5659_PDM1_R_SFT, rt5659_pdm_src); RT5659_PDM1_R_SFT, rt5659_pdm_src);
...@@ -2230,7 +2230,7 @@ static const char * const rt5659_spdif_src[] = { ...@@ -2230,7 +2230,7 @@ static const char * const rt5659_spdif_src[] = {
"IF1_DAC1", "IF1_DAC2", "IF2_DAC", "IF3_DAC" "IF1_DAC1", "IF1_DAC2", "IF2_DAC", "IF3_DAC"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_spdif_enum, RT5659_SPDIF_CTRL, rt5659_spdif_enum, RT5659_SPDIF_CTRL,
RT5659_SPDIF_SEL_SFT, rt5659_spdif_src); RT5659_SPDIF_SEL_SFT, rt5659_spdif_src);
...@@ -2250,7 +2250,7 @@ static const char * const rt5659_rx_adc_data_src[] = { ...@@ -2250,7 +2250,7 @@ static const char * const rt5659_rx_adc_data_src[] = {
"NUL:AD2:DAC:AD1", "NUL:DAC:DAC:AD2", "NUL:DAC:AD2:DAC" "NUL:AD2:DAC:AD1", "NUL:DAC:DAC:AD2", "NUL:DAC:AD2:DAC"
}; };
static const SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5659_rx_adc_data_enum, RT5659_TDM_CTRL_2, rt5659_rx_adc_data_enum, RT5659_TDM_CTRL_2,
RT5659_ADCDAT_SRC_SFT, rt5659_rx_adc_data_src); RT5659_ADCDAT_SRC_SFT, rt5659_rx_adc_data_src);
...@@ -4018,7 +4018,7 @@ static int rt5659_i2c_probe(struct i2c_client *i2c, ...@@ -4018,7 +4018,7 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
GPIOD_OUT_HIGH); GPIOD_OUT_HIGH);
/* Sleep for 300 ms miniumum */ /* Sleep for 300 ms miniumum */
usleep_range(300000, 350000); msleep(300);
rt5659->regmap = devm_regmap_init_i2c(i2c, &rt5659_regmap); rt5659->regmap = devm_regmap_init_i2c(i2c, &rt5659_regmap);
if (IS_ERR(rt5659->regmap)) { if (IS_ERR(rt5659->regmap)) {
...@@ -4230,10 +4230,9 @@ static struct acpi_device_id rt5659_acpi_match[] = { ...@@ -4230,10 +4230,9 @@ static struct acpi_device_id rt5659_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, rt5659_acpi_match); MODULE_DEVICE_TABLE(acpi, rt5659_acpi_match);
#endif #endif
struct i2c_driver rt5659_i2c_driver = { static struct i2c_driver rt5659_i2c_driver = {
.driver = { .driver = {
.name = "rt5659", .name = "rt5659",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(rt5659_of_match), .of_match_table = of_match_ptr(rt5659_of_match),
.acpi_match_table = ACPI_PTR(rt5659_acpi_match), .acpi_match_table = ACPI_PTR(rt5659_acpi_match),
}, },
......
...@@ -526,10 +526,10 @@ static const char * const rt5660_data_select[] = { ...@@ -526,10 +526,10 @@ static const char * const rt5660_data_select[] = {
"L/R", "R/L", "L/L", "R/R" "L/R", "R/L", "L/L", "R/R"
}; };
static const SOC_ENUM_SINGLE_DECL(rt5660_if1_dac_enum, static SOC_ENUM_SINGLE_DECL(rt5660_if1_dac_enum,
RT5660_DIG_INF1_DATA, RT5660_IF1_DAC_IN_SFT, rt5660_data_select); RT5660_DIG_INF1_DATA, RT5660_IF1_DAC_IN_SFT, rt5660_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5660_if1_adc_enum, static SOC_ENUM_SINGLE_DECL(rt5660_if1_adc_enum,
RT5660_DIG_INF1_DATA, RT5660_IF1_ADC_IN_SFT, rt5660_data_select); RT5660_DIG_INF1_DATA, RT5660_IF1_ADC_IN_SFT, rt5660_data_select);
static const struct snd_kcontrol_new rt5660_if1_dac_swap_mux = static const struct snd_kcontrol_new rt5660_if1_dac_swap_mux =
...@@ -1152,7 +1152,7 @@ static int rt5660_resume(struct snd_soc_codec *codec) ...@@ -1152,7 +1152,7 @@ static int rt5660_resume(struct snd_soc_codec *codec)
struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec); struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
if (rt5660->pdata.poweroff_codec_in_suspend) if (rt5660->pdata.poweroff_codec_in_suspend)
usleep_range(350000, 400000); msleep(350);
regcache_cache_only(rt5660->regmap, false); regcache_cache_only(rt5660->regmap, false);
regcache_sync(rt5660->regmap); regcache_sync(rt5660->regmap);
......
...@@ -2814,6 +2814,7 @@ MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id); ...@@ -2814,6 +2814,7 @@ MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id);
static const struct acpi_device_id rt5670_acpi_match[] = { static const struct acpi_device_id rt5670_acpi_match[] = {
{ "10EC5670", 0}, { "10EC5670", 0},
{ "10EC5672", 0}, { "10EC5672", 0},
{ "10EC5640", 0}, /* quirk */
{ }, { },
}; };
MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match); MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match);
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/pm_qos.h> #include <linux/pm_qos.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
......
...@@ -1393,6 +1393,12 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power) ...@@ -1393,6 +1393,12 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c); snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c);
snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d); snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d);
} }
/*
* Delay is needed to reduce pop-noise after syncing back the
* registers
*/
mdelay(50);
} else { } else {
/* /*
* Do soft reset to this codec instance in order to clear * Do soft reset to this codec instance in order to clear
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/mutex.h> #include <linux/mutex.h>
......
...@@ -855,6 +855,8 @@ ARIZONA_LHPF_CONTROL("LHPF2 Coefficients", ARIZONA_HPLPF2_2), ...@@ -855,6 +855,8 @@ ARIZONA_LHPF_CONTROL("LHPF2 Coefficients", ARIZONA_HPLPF2_2),
ARIZONA_LHPF_CONTROL("LHPF3 Coefficients", ARIZONA_HPLPF3_2), ARIZONA_LHPF_CONTROL("LHPF3 Coefficients", ARIZONA_HPLPF3_2),
ARIZONA_LHPF_CONTROL("LHPF4 Coefficients", ARIZONA_HPLPF4_2), ARIZONA_LHPF_CONTROL("LHPF4 Coefficients", ARIZONA_HPLPF4_2),
WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
...@@ -1944,7 +1946,10 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) ...@@ -1944,7 +1946,10 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
if (ret) if (ret)
goto err_adsp2_codec_probe; goto err_adsp2_codec_probe;
arizona_init_spk(codec); ret = arizona_init_spk(codec);
if (ret < 0)
return ret;
arizona_init_gpio(codec); arizona_init_gpio(codec);
arizona_init_notifiers(codec); arizona_init_notifiers(codec);
......
...@@ -778,6 +778,11 @@ SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]), ...@@ -778,6 +778,11 @@ SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]), SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]),
SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1), SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
WM_ADSP2_PRELOAD_SWITCH("DSP2", 2),
WM_ADSP2_PRELOAD_SWITCH("DSP3", 3),
WM_ADSP2_PRELOAD_SWITCH("DSP4", 4),
ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
...@@ -2279,7 +2284,10 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) ...@@ -2279,7 +2284,10 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
priv->core.arizona->dapm = dapm; priv->core.arizona->dapm = dapm;
arizona_init_spk(codec); ret = arizona_init_spk(codec);
if (ret < 0)
return ret;
arizona_init_gpio(codec); arizona_init_gpio(codec);
arizona_init_mono(codec); arizona_init_mono(codec);
arizona_init_notifiers(codec); arizona_init_notifiers(codec);
......
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
#define WM8731_CACHEREGNUM 10 #define WM8731_CACHEREGNUM 10
#define WM8731_SYSCLK_MCLK 0
#define WM8731_SYSCLK_XTAL 1 #define WM8731_SYSCLK_XTAL 1
#define WM8731_SYSCLK_MCLK 2
#define WM8731_DAI 0 #define WM8731_DAI 0
......
...@@ -37,8 +37,6 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = { ...@@ -37,8 +37,6 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
"DVDD", "DVDD",
}; };
#define WM8741_NUM_RATES 6
/* codec private data */ /* codec private data */
struct wm8741_priv { struct wm8741_priv {
struct wm8741_platform_data pdata; struct wm8741_platform_data pdata;
......
...@@ -280,6 +280,7 @@ static const DECLARE_TLV_DB_SCALE(voice_mix_tlv, -1200, 300, 0); ...@@ -280,6 +280,7 @@ static const DECLARE_TLV_DB_SCALE(voice_mix_tlv, -1200, 300, 0);
static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0); static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
static const struct snd_kcontrol_new wm8753_snd_controls[] = { static const struct snd_kcontrol_new wm8753_snd_controls[] = {
SOC_SINGLE("Hi-Fi DAC Left/Right channel Swap", WM8753_HIFI, 5, 1, 0),
SOC_DOUBLE_R_TLV("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0, dac_tlv), SOC_DOUBLE_R_TLV("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0, dac_tlv),
SOC_DOUBLE_R_TLV("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0, SOC_DOUBLE_R_TLV("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0,
...@@ -1087,7 +1088,7 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec, ...@@ -1087,7 +1088,7 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
{ {
u16 ioctl, hifi; u16 ioctl, hifi;
hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f; hifi = snd_soc_read(codec, WM8753_HIFI) & 0x013f;
ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae; ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
/* set master/slave audio interface */ /* set master/slave audio interface */
......
...@@ -1062,8 +1062,12 @@ static int wm8997_codec_probe(struct snd_soc_codec *codec) ...@@ -1062,8 +1062,12 @@ static int wm8997_codec_probe(struct snd_soc_codec *codec)
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec); struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec);
int ret;
ret = arizona_init_spk(codec);
if (ret < 0)
return ret;
arizona_init_spk(codec);
arizona_init_notifiers(codec); arizona_init_notifiers(codec);
snd_soc_component_disable_pin(component, "HAPTICS"); snd_soc_component_disable_pin(component, "HAPTICS");
......
...@@ -1321,10 +1321,14 @@ static int wm8998_codec_probe(struct snd_soc_codec *codec) ...@@ -1321,10 +1321,14 @@ static int wm8998_codec_probe(struct snd_soc_codec *codec)
struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec); struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
int ret;
priv->core.arizona->dapm = dapm; priv->core.arizona->dapm = dapm;
arizona_init_spk(codec); ret = arizona_init_spk(codec);
if (ret < 0)
return ret;
arizona_init_gpio(codec); arizona_init_gpio(codec);
arizona_init_notifiers(codec); arizona_init_notifiers(codec);
......
此差异已折叠。
...@@ -62,6 +62,7 @@ struct wm_adsp { ...@@ -62,6 +62,7 @@ struct wm_adsp {
int fw; int fw;
int fw_ver; int fw_ver;
bool preloaded;
bool booted; bool booted;
bool running; bool running;
...@@ -86,7 +87,12 @@ struct wm_adsp { ...@@ -86,7 +87,12 @@ struct wm_adsp {
SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
#define WM_ADSP2_PRELOAD_SWITCH(wname, num) \
SOC_SINGLE_EXT(wname " Preload Switch", SND_SOC_NOPM, num, 1, 0, \
wm_adsp2_preloader_get, wm_adsp2_preloader_put)
#define WM_ADSP2(wname, num, event_fn) \ #define WM_ADSP2(wname, num, event_fn) \
SND_SOC_DAPM_SPK(wname " Preload", NULL), \
{ .id = snd_soc_dapm_supply, .name = wname " Preloader", \ { .id = snd_soc_dapm_supply, .name = wname " Preloader", \
.reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \ .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \ .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \
...@@ -110,6 +116,11 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, ...@@ -110,6 +116,11 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
int wm_adsp2_event(struct snd_soc_dapm_widget *w, int wm_adsp2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event); struct snd_kcontrol *kcontrol, int event);
int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream); int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream);
int wm_adsp_compr_free(struct snd_compr_stream *stream); int wm_adsp_compr_free(struct snd_compr_stream *stream);
int wm_adsp_compr_set_params(struct snd_compr_stream *stream, int wm_adsp_compr_set_params(struct snd_compr_stream *stream,
......
...@@ -358,13 +358,20 @@ static struct snd_soc_card evm_soc_card = { ...@@ -358,13 +358,20 @@ static struct snd_soc_card evm_soc_card = {
static int davinci_evm_probe(struct platform_device *pdev) static int davinci_evm_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
const struct of_device_id *match = const struct of_device_id *match;
of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev); struct snd_soc_dai_link *dai;
struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data;
struct snd_soc_card_drvdata_davinci *drvdata = NULL; struct snd_soc_card_drvdata_davinci *drvdata = NULL;
struct clk *mclk; struct clk *mclk;
int ret = 0; int ret = 0;
match = of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
if (!match) {
dev_err(&pdev->dev, "Error: No device match found\n");
return -ENODEV;
}
dai = (struct snd_soc_dai_link *) match->data;
evm_soc_card.dai_link = dai; evm_soc_card.dai_link = dai;
dai->codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0); dai->codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0);
......
...@@ -121,9 +121,14 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id) ...@@ -121,9 +121,14 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
irq_valid = true; irq_valid = true;
} }
/* Data available. Record mode not supported in PIO mode */ /*
if (isr[i] & ISR_RXDA) * Data available. Retrieve samples from FIFO
* NOTE: Only two channels supported
*/
if ((isr[i] & ISR_RXDA) && (i == 0) && dev->use_pio) {
dw_pcm_pop_rx(dev);
irq_valid = true; irq_valid = true;
}
/* Error Handling: TX */ /* Error Handling: TX */
if (isr[i] & ISR_TXFO) { if (isr[i] & ISR_TXFO) {
......
此差异已折叠。
...@@ -105,20 +105,27 @@ struct dw_i2s_dev { ...@@ -105,20 +105,27 @@ struct dw_i2s_dev {
struct i2s_clk_config_data config; struct i2s_clk_config_data config;
int (*i2s_clk_cfg)(struct i2s_clk_config_data *config); int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
/* data related to PIO transfers (TX) */ /* data related to PIO transfers */
bool use_pio; bool use_pio;
struct snd_pcm_substream __rcu *tx_substream; struct snd_pcm_substream __rcu *tx_substream;
struct snd_pcm_substream __rcu *rx_substream;
unsigned int (*tx_fn)(struct dw_i2s_dev *dev, unsigned int (*tx_fn)(struct dw_i2s_dev *dev,
struct snd_pcm_runtime *runtime, unsigned int tx_ptr, struct snd_pcm_runtime *runtime, unsigned int tx_ptr,
bool *period_elapsed); bool *period_elapsed);
unsigned int (*rx_fn)(struct dw_i2s_dev *dev,
struct snd_pcm_runtime *runtime, unsigned int rx_ptr,
bool *period_elapsed);
unsigned int tx_ptr; unsigned int tx_ptr;
unsigned int rx_ptr;
}; };
#if IS_ENABLED(CONFIG_SND_DESIGNWARE_PCM) #if IS_ENABLED(CONFIG_SND_DESIGNWARE_PCM)
void dw_pcm_push_tx(struct dw_i2s_dev *dev); void dw_pcm_push_tx(struct dw_i2s_dev *dev);
void dw_pcm_pop_rx(struct dw_i2s_dev *dev);
int dw_pcm_register(struct platform_device *pdev); int dw_pcm_register(struct platform_device *pdev);
#else #else
void dw_pcm_push_tx(struct dw_i2s_dev *dev) { } void dw_pcm_push_tx(struct dw_i2s_dev *dev) { }
void dw_pcm_pop_rx(struct dw_i2s_dev *dev) { }
int dw_pcm_register(struct platform_device *pdev) int dw_pcm_register(struct platform_device *pdev)
{ {
return -EINVAL; return -EINVAL;
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <sound/soc.h> #include <sound/soc.h>
#include "mpc5200_dma.h" #include "mpc5200_dma.h"
#include "mpc5200_psc_ac97.h"
#define DRV_NAME "efika-audio-fabric" #define DRV_NAME "efika-audio-fabric"
......
...@@ -668,7 +668,7 @@ static struct snd_soc_dai_driver fsl_sai_dai = { ...@@ -668,7 +668,7 @@ static struct snd_soc_dai_driver fsl_sai_dai = {
.playback = { .playback = {
.stream_name = "CPU-Playback", .stream_name = "CPU-Playback",
.channels_min = 1, .channels_min = 1,
.channels_max = 2, .channels_max = 32,
.rate_min = 8000, .rate_min = 8000,
.rate_max = 192000, .rate_max = 192000,
.rates = SNDRV_PCM_RATE_KNOT, .rates = SNDRV_PCM_RATE_KNOT,
...@@ -677,7 +677,7 @@ static struct snd_soc_dai_driver fsl_sai_dai = { ...@@ -677,7 +677,7 @@ static struct snd_soc_dai_driver fsl_sai_dai = {
.capture = { .capture = {
.stream_name = "CPU-Capture", .stream_name = "CPU-Capture",
.channels_min = 1, .channels_min = 1,
.channels_max = 2, .channels_max = 32,
.rate_min = 8000, .rate_min = 8000,
.rate_max = 192000, .rate_max = 192000,
.rates = SNDRV_PCM_RATE_KNOT, .rates = SNDRV_PCM_RATE_KNOT,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册