Merge remote-tracking branches 'asoc/topic/da7213', 'asoc/topic/da732x', 'asoc/topic/da9055', 'asoc/topic/davinci', 'asoc/topic/fsl', 'asoc/topic/fsl-esai', 'asoc/topic/fsl-sai' and 'asoc/topic/fsl-spdif' into asoc-next
This commit is contained in:
parent
696cda5b5b
c99f8b216c
30812cca63
9839ce9360
64ebdec36a
8db0d35bee
eaba603fc7
a3f7dcc9cc
86f28d7643
commit
84f6965e2b
|
@ -0,0 +1,22 @@
|
|||
* Dialog DA9055 Audio CODEC
|
||||
|
||||
DA9055 provides Audio CODEC support (I2C only).
|
||||
|
||||
The Audio CODEC device in DA9055 has it's own I2C address which is configurable,
|
||||
so the device is instantiated separately from the PMIC (MFD) device.
|
||||
|
||||
For details on accompanying PMIC I2C device, see the following:
|
||||
Documentation/devicetree/bindings/mfd/da9055.txt
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: "dlg,da9055-codec"
|
||||
- reg: Specifies the I2C slave address
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
codec: da9055-codec@1a {
|
||||
compatible = "dlg,da9055-codec";
|
||||
reg = <0x1a>;
|
||||
};
|
|
@ -5,12 +5,19 @@ Required properties:
|
|||
- ti,model : The user-visible name of this sound complex.
|
||||
- ti,audio-codec : The phandle of the TLV320AIC3x audio codec
|
||||
- ti,mcasp-controller : The phandle of the McASP controller
|
||||
- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec
|
||||
- ti,audio-routing : A list of the connections between audio components.
|
||||
Each entry is a pair of strings, the first being the connection's sink,
|
||||
the second being the connection's source. Valid names for sources and
|
||||
sinks are the codec's pins, and the jacks on the board:
|
||||
|
||||
Optional properties:
|
||||
- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec.
|
||||
- clocks : Reference to the master clock
|
||||
- clock-names : The clock should be named "mclk"
|
||||
- Either codec-clock-rate or the codec-clock reference has to be defined. If
|
||||
the both are defined the driver attempts to set referenced clock to the
|
||||
defined rate and takes the rate from the clock reference.
|
||||
|
||||
Board connectors:
|
||||
|
||||
* Headphone Jack
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
Audio complex for Eukrea boards with tlv320aic23 codec.
|
||||
|
||||
Required properties:
|
||||
- compatible : "eukrea,asoc-tlv320"
|
||||
- eukrea,model : The user-visible name of this sound complex.
|
||||
- ssi-controller : The phandle of the SSI controller.
|
||||
- fsl,mux-int-port : The internal port of the i.MX audio muxer (AUDMUX).
|
||||
- fsl,mux-ext-port : The external port of the i.MX audio muxer.
|
||||
|
||||
Note: The AUDMUX port numbering should start at 1, which is consistent with
|
||||
hardware manual.
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "eukrea,asoc-tlv320";
|
||||
eukrea,model = "imx51-eukrea-tlv320aic23";
|
||||
ssi-controller = <&ssi2>;
|
||||
fsl,mux-int-port = <2>;
|
||||
fsl,mux-ext-port = <3>;
|
||||
};
|
|
@ -34,6 +34,10 @@ Required properties:
|
|||
that ESAI would work in the synchronous mode, which means all the settings
|
||||
for Receiving would be duplicated from Transmition related registers.
|
||||
|
||||
- big-endian : If this property is absent, the native endian mode will
|
||||
be in use as default, or the big endian mode will be in use for all the
|
||||
device registers.
|
||||
|
||||
Example:
|
||||
|
||||
esai: esai@02024000 {
|
||||
|
@ -46,5 +50,6 @@ esai: esai@02024000 {
|
|||
dma-names = "rx", "tx";
|
||||
fsl,fifo-depth = <128>;
|
||||
fsl,esai-synchronous;
|
||||
big-endian;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
|
@ -29,6 +29,10 @@ Required properties:
|
|||
can also be referred to TxClk_Source
|
||||
bit of register SPDIF_STC.
|
||||
|
||||
- big-endian : If this property is absent, the native endian mode will
|
||||
be in use as default, or the big endian mode will be in use for all the
|
||||
device registers.
|
||||
|
||||
Example:
|
||||
|
||||
spdif: spdif@02004000 {
|
||||
|
@ -50,5 +54,6 @@ spdif: spdif@02004000 {
|
|||
"rxtx5", "rxtx6",
|
||||
"rxtx7";
|
||||
|
||||
big-endian;
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include <linux/genalloc.h>
|
||||
|
||||
struct snd_platform_data {
|
||||
struct davinci_mcasp_pdata {
|
||||
u32 tx_dma_offset;
|
||||
u32 rx_dma_offset;
|
||||
int asp_chan_q; /* event queue number for ASP channel */
|
||||
|
@ -87,6 +87,8 @@ struct snd_platform_data {
|
|||
int tx_dma_channel;
|
||||
int rx_dma_channel;
|
||||
};
|
||||
/* TODO: Fix arch/arm/mach-davinci/ users and remove this define */
|
||||
#define snd_platform_data davinci_mcasp_pdata
|
||||
|
||||
enum {
|
||||
MCASP_VERSION_1 = 0, /* DM646x */
|
||||
|
|
|
@ -58,6 +58,6 @@ config SND_AT91_SOC_AFEB9260
|
|||
depends on ARCH_AT91 && ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
|
||||
select SND_ATMEL_SOC_PDC
|
||||
select SND_ATMEL_SOC_SSC
|
||||
select SND_SOC_TLV320AIC23
|
||||
select SND_SOC_TLV320AIC23_I2C
|
||||
help
|
||||
Say Y here to support sound on AFEB9260 board.
|
||||
|
|
|
@ -18,7 +18,7 @@ config SND_EP93XX_SOC_SNAPPERCL15
|
|||
tristate "SoC Audio support for Bluewater Systems Snapper CL15 module"
|
||||
depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15
|
||||
select SND_EP93XX_SOC_I2S
|
||||
select SND_SOC_TLV320AIC23
|
||||
select SND_SOC_TLV320AIC23_I2C
|
||||
help
|
||||
Say Y or M here if you want to add support for I2S audio on the
|
||||
Bluewater Systems Snapper CL15 module.
|
||||
|
|
|
@ -80,7 +80,8 @@ config SND_SOC_ALL_CODECS
|
|||
select SND_SOC_STA529 if I2C
|
||||
select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
|
||||
select SND_SOC_TAS5086 if I2C
|
||||
select SND_SOC_TLV320AIC23 if I2C
|
||||
select SND_SOC_TLV320AIC23_I2C if I2C
|
||||
select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
|
||||
select SND_SOC_TLV320AIC26 if SPI_MASTER
|
||||
select SND_SOC_TLV320AIC32X4 if I2C
|
||||
select SND_SOC_TLV320AIC3X if I2C
|
||||
|
@ -422,6 +423,14 @@ config SND_SOC_TAS5086
|
|||
config SND_SOC_TLV320AIC23
|
||||
tristate
|
||||
|
||||
config SND_SOC_TLV320AIC23_I2C
|
||||
tristate
|
||||
select SND_SOC_TLV320AIC23
|
||||
|
||||
config SND_SOC_TLV320AIC23_SPI
|
||||
tristate
|
||||
select SND_SOC_TLV320AIC23
|
||||
|
||||
config SND_SOC_TLV320AIC26
|
||||
tristate
|
||||
depends on SPI
|
||||
|
|
|
@ -73,6 +73,8 @@ snd-soc-sta529-objs := sta529.o
|
|||
snd-soc-stac9766-objs := stac9766.o
|
||||
snd-soc-tas5086-objs := tas5086.o
|
||||
snd-soc-tlv320aic23-objs := tlv320aic23.o
|
||||
snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
|
||||
snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
|
||||
snd-soc-tlv320aic26-objs := tlv320aic26.o
|
||||
snd-soc-tlv320aic3x-objs := tlv320aic3x.o
|
||||
snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
|
||||
|
@ -213,6 +215,8 @@ obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
|
|||
obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
|
||||
obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
|
||||
|
|
|
@ -63,30 +63,30 @@ static const char * const da7213_voice_hpf_corner_txt[] = {
|
|||
"2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_dac_voice_hpf_corner =
|
||||
SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT,
|
||||
DA7213_VOICE_HPF_CORNER_MAX,
|
||||
da7213_voice_hpf_corner_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_dac_voice_hpf_corner,
|
||||
DA7213_DAC_FILTERS1,
|
||||
DA7213_VOICE_HPF_CORNER_SHIFT,
|
||||
da7213_voice_hpf_corner_txt);
|
||||
|
||||
static const struct soc_enum da7213_adc_voice_hpf_corner =
|
||||
SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT,
|
||||
DA7213_VOICE_HPF_CORNER_MAX,
|
||||
da7213_voice_hpf_corner_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_adc_voice_hpf_corner,
|
||||
DA7213_ADC_FILTERS1,
|
||||
DA7213_VOICE_HPF_CORNER_SHIFT,
|
||||
da7213_voice_hpf_corner_txt);
|
||||
|
||||
/* ADC and DAC high pass filter cutoff value */
|
||||
static const char * const da7213_audio_hpf_corner_txt[] = {
|
||||
"Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_dac_audio_hpf_corner =
|
||||
SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT,
|
||||
DA7213_AUDIO_HPF_CORNER_MAX,
|
||||
da7213_audio_hpf_corner_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_dac_audio_hpf_corner,
|
||||
DA7213_DAC_FILTERS1
|
||||
, DA7213_AUDIO_HPF_CORNER_SHIFT,
|
||||
da7213_audio_hpf_corner_txt);
|
||||
|
||||
static const struct soc_enum da7213_adc_audio_hpf_corner =
|
||||
SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT,
|
||||
DA7213_AUDIO_HPF_CORNER_MAX,
|
||||
da7213_audio_hpf_corner_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_adc_audio_hpf_corner,
|
||||
DA7213_ADC_FILTERS1,
|
||||
DA7213_AUDIO_HPF_CORNER_SHIFT,
|
||||
da7213_audio_hpf_corner_txt);
|
||||
|
||||
/* Gain ramping rate value */
|
||||
static const char * const da7213_gain_ramp_rate_txt[] = {
|
||||
|
@ -94,52 +94,50 @@ static const char * const da7213_gain_ramp_rate_txt[] = {
|
|||
"nominal rate / 32"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_gain_ramp_rate =
|
||||
SOC_ENUM_SINGLE(DA7213_GAIN_RAMP_CTRL, DA7213_GAIN_RAMP_RATE_SHIFT,
|
||||
DA7213_GAIN_RAMP_RATE_MAX, da7213_gain_ramp_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_gain_ramp_rate,
|
||||
DA7213_GAIN_RAMP_CTRL,
|
||||
DA7213_GAIN_RAMP_RATE_SHIFT,
|
||||
da7213_gain_ramp_rate_txt);
|
||||
|
||||
/* DAC noise gate setup time value */
|
||||
static const char * const da7213_dac_ng_setup_time_txt[] = {
|
||||
"256 samples", "512 samples", "1024 samples", "2048 samples"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_dac_ng_setup_time =
|
||||
SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
|
||||
DA7213_DAC_NG_SETUP_TIME_SHIFT,
|
||||
DA7213_DAC_NG_SETUP_TIME_MAX,
|
||||
da7213_dac_ng_setup_time_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_setup_time,
|
||||
DA7213_DAC_NG_SETUP_TIME,
|
||||
DA7213_DAC_NG_SETUP_TIME_SHIFT,
|
||||
da7213_dac_ng_setup_time_txt);
|
||||
|
||||
/* DAC noise gate rampup rate value */
|
||||
static const char * const da7213_dac_ng_rampup_txt[] = {
|
||||
"0.02 ms/dB", "0.16 ms/dB"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_dac_ng_rampup_rate =
|
||||
SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
|
||||
DA7213_DAC_NG_RAMPUP_RATE_SHIFT,
|
||||
DA7213_DAC_NG_RAMP_RATE_MAX,
|
||||
da7213_dac_ng_rampup_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_rampup_rate,
|
||||
DA7213_DAC_NG_SETUP_TIME,
|
||||
DA7213_DAC_NG_RAMPUP_RATE_SHIFT,
|
||||
da7213_dac_ng_rampup_txt);
|
||||
|
||||
/* DAC noise gate rampdown rate value */
|
||||
static const char * const da7213_dac_ng_rampdown_txt[] = {
|
||||
"0.64 ms/dB", "20.48 ms/dB"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_dac_ng_rampdown_rate =
|
||||
SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
|
||||
DA7213_DAC_NG_RAMPDN_RATE_SHIFT,
|
||||
DA7213_DAC_NG_RAMP_RATE_MAX,
|
||||
da7213_dac_ng_rampdown_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_rampdown_rate,
|
||||
DA7213_DAC_NG_SETUP_TIME,
|
||||
DA7213_DAC_NG_RAMPDN_RATE_SHIFT,
|
||||
da7213_dac_ng_rampdown_txt);
|
||||
|
||||
/* DAC soft mute rate value */
|
||||
static const char * const da7213_dac_soft_mute_rate_txt[] = {
|
||||
"1", "2", "4", "8", "16", "32", "64"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_dac_soft_mute_rate =
|
||||
SOC_ENUM_SINGLE(DA7213_DAC_FILTERS5, DA7213_DAC_SOFTMUTE_RATE_SHIFT,
|
||||
DA7213_DAC_SOFTMUTE_RATE_MAX,
|
||||
da7213_dac_soft_mute_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_dac_soft_mute_rate,
|
||||
DA7213_DAC_FILTERS5,
|
||||
DA7213_DAC_SOFTMUTE_RATE_SHIFT,
|
||||
da7213_dac_soft_mute_rate_txt);
|
||||
|
||||
/* ALC Attack Rate select */
|
||||
static const char * const da7213_alc_attack_rate_txt[] = {
|
||||
|
@ -147,9 +145,10 @@ static const char * const da7213_alc_attack_rate_txt[] = {
|
|||
"5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_alc_attack_rate =
|
||||
SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_ATTACK_SHIFT,
|
||||
DA7213_ALC_ATTACK_MAX, da7213_alc_attack_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_alc_attack_rate,
|
||||
DA7213_ALC_CTRL2,
|
||||
DA7213_ALC_ATTACK_SHIFT,
|
||||
da7213_alc_attack_rate_txt);
|
||||
|
||||
/* ALC Release Rate select */
|
||||
static const char * const da7213_alc_release_rate_txt[] = {
|
||||
|
@ -157,9 +156,10 @@ static const char * const da7213_alc_release_rate_txt[] = {
|
|||
"11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_alc_release_rate =
|
||||
SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_RELEASE_SHIFT,
|
||||
DA7213_ALC_RELEASE_MAX, da7213_alc_release_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_alc_release_rate,
|
||||
DA7213_ALC_CTRL2,
|
||||
DA7213_ALC_RELEASE_SHIFT,
|
||||
da7213_alc_release_rate_txt);
|
||||
|
||||
/* ALC Hold Time select */
|
||||
static const char * const da7213_alc_hold_time_txt[] = {
|
||||
|
@ -168,22 +168,25 @@ static const char * const da7213_alc_hold_time_txt[] = {
|
|||
"253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_alc_hold_time =
|
||||
SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_HOLD_SHIFT,
|
||||
DA7213_ALC_HOLD_MAX, da7213_alc_hold_time_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_alc_hold_time,
|
||||
DA7213_ALC_CTRL3,
|
||||
DA7213_ALC_HOLD_SHIFT,
|
||||
da7213_alc_hold_time_txt);
|
||||
|
||||
/* ALC Input Signal Tracking rate select */
|
||||
static const char * const da7213_alc_integ_rate_txt[] = {
|
||||
"1/4", "1/16", "1/256", "1/65536"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_alc_integ_attack_rate =
|
||||
SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_ATTACK_SHIFT,
|
||||
DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_attack_rate,
|
||||
DA7213_ALC_CTRL3,
|
||||
DA7213_ALC_INTEG_ATTACK_SHIFT,
|
||||
da7213_alc_integ_rate_txt);
|
||||
|
||||
static const struct soc_enum da7213_alc_integ_release_rate =
|
||||
SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_RELEASE_SHIFT,
|
||||
DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_release_rate,
|
||||
DA7213_ALC_CTRL3,
|
||||
DA7213_ALC_INTEG_RELEASE_SHIFT,
|
||||
da7213_alc_integ_rate_txt);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -584,15 +587,17 @@ static const char * const da7213_mic_amp_in_sel_txt[] = {
|
|||
"Differential", "MIC_P", "MIC_N"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_mic_1_amp_in_sel =
|
||||
SOC_ENUM_SINGLE(DA7213_MIC_1_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT,
|
||||
DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_mic_1_amp_in_sel,
|
||||
DA7213_MIC_1_CTRL,
|
||||
DA7213_MIC_AMP_IN_SEL_SHIFT,
|
||||
da7213_mic_amp_in_sel_txt);
|
||||
static const struct snd_kcontrol_new da7213_mic_1_amp_in_sel_mux =
|
||||
SOC_DAPM_ENUM("Mic 1 Amp Source MUX", da7213_mic_1_amp_in_sel);
|
||||
|
||||
static const struct soc_enum da7213_mic_2_amp_in_sel =
|
||||
SOC_ENUM_SINGLE(DA7213_MIC_2_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT,
|
||||
DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_mic_2_amp_in_sel,
|
||||
DA7213_MIC_2_CTRL,
|
||||
DA7213_MIC_AMP_IN_SEL_SHIFT,
|
||||
da7213_mic_amp_in_sel_txt);
|
||||
static const struct snd_kcontrol_new da7213_mic_2_amp_in_sel_mux =
|
||||
SOC_DAPM_ENUM("Mic 2 Amp Source MUX", da7213_mic_2_amp_in_sel);
|
||||
|
||||
|
@ -601,15 +606,17 @@ static const char * const da7213_dai_src_txt[] = {
|
|||
"ADC Left", "ADC Right", "DAI Input Left", "DAI Input Right"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_dai_l_src =
|
||||
SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_L_SRC_SHIFT,
|
||||
DA7213_DAI_SRC_MAX, da7213_dai_src_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_dai_l_src,
|
||||
DA7213_DIG_ROUTING_DAI,
|
||||
DA7213_DAI_L_SRC_SHIFT,
|
||||
da7213_dai_src_txt);
|
||||
static const struct snd_kcontrol_new da7213_dai_l_src_mux =
|
||||
SOC_DAPM_ENUM("DAI Left Source MUX", da7213_dai_l_src);
|
||||
|
||||
static const struct soc_enum da7213_dai_r_src =
|
||||
SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_R_SRC_SHIFT,
|
||||
DA7213_DAI_SRC_MAX, da7213_dai_src_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_dai_r_src,
|
||||
DA7213_DIG_ROUTING_DAI,
|
||||
DA7213_DAI_R_SRC_SHIFT,
|
||||
da7213_dai_src_txt);
|
||||
static const struct snd_kcontrol_new da7213_dai_r_src_mux =
|
||||
SOC_DAPM_ENUM("DAI Right Source MUX", da7213_dai_r_src);
|
||||
|
||||
|
@ -619,15 +626,17 @@ static const char * const da7213_dac_src_txt[] = {
|
|||
"DAI Input Right"
|
||||
};
|
||||
|
||||
static const struct soc_enum da7213_dac_l_src =
|
||||
SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_L_SRC_SHIFT,
|
||||
DA7213_DAC_SRC_MAX, da7213_dac_src_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_dac_l_src,
|
||||
DA7213_DIG_ROUTING_DAC,
|
||||
DA7213_DAC_L_SRC_SHIFT,
|
||||
da7213_dac_src_txt);
|
||||
static const struct snd_kcontrol_new da7213_dac_l_src_mux =
|
||||
SOC_DAPM_ENUM("DAC Left Source MUX", da7213_dac_l_src);
|
||||
|
||||
static const struct soc_enum da7213_dac_r_src =
|
||||
SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_R_SRC_SHIFT,
|
||||
DA7213_DAC_SRC_MAX, da7213_dac_src_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da7213_dac_r_src,
|
||||
DA7213_DIG_ROUTING_DAC,
|
||||
DA7213_DAC_R_SRC_SHIFT,
|
||||
da7213_dac_src_txt);
|
||||
static const struct snd_kcontrol_new da7213_dac_r_src_mux =
|
||||
SOC_DAPM_ENUM("DAC Right Source MUX", da7213_dac_r_src);
|
||||
|
||||
|
|
|
@ -269,81 +269,65 @@ static const char *da732x_hpf_voice[] = {
|
|||
"150Hz", "200Hz", "300Hz", "400Hz"
|
||||
};
|
||||
|
||||
static const struct soc_enum da732x_dac1_hpf_mode_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT,
|
||||
DA732X_HPF_MODE_MAX, da732x_hpf_mode)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_dac1_hpf_mode_enum,
|
||||
DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT,
|
||||
da732x_hpf_mode);
|
||||
|
||||
static const struct soc_enum da732x_dac2_hpf_mode_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT,
|
||||
DA732X_HPF_MODE_MAX, da732x_hpf_mode)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_dac2_hpf_mode_enum,
|
||||
DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT,
|
||||
da732x_hpf_mode);
|
||||
|
||||
static const struct soc_enum da732x_dac3_hpf_mode_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT,
|
||||
DA732X_HPF_MODE_MAX, da732x_hpf_mode)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_dac3_hpf_mode_enum,
|
||||
DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT,
|
||||
da732x_hpf_mode);
|
||||
|
||||
static const struct soc_enum da732x_adc1_hpf_mode_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT,
|
||||
DA732X_HPF_MODE_MAX, da732x_hpf_mode)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_adc1_hpf_mode_enum,
|
||||
DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT,
|
||||
da732x_hpf_mode);
|
||||
|
||||
static const struct soc_enum da732x_adc2_hpf_mode_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT,
|
||||
DA732X_HPF_MODE_MAX, da732x_hpf_mode)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_adc2_hpf_mode_enum,
|
||||
DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT,
|
||||
da732x_hpf_mode);
|
||||
|
||||
static const struct soc_enum da732x_dac1_hp_filter_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||
DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_dac1_hp_filter_enum,
|
||||
DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||
da732x_hpf_music);
|
||||
|
||||
static const struct soc_enum da732x_dac2_hp_filter_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||
DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_dac2_hp_filter_enum,
|
||||
DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||
da732x_hpf_music);
|
||||
|
||||
static const struct soc_enum da732x_dac3_hp_filter_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||
DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_dac3_hp_filter_enum,
|
||||
DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||
da732x_hpf_music);
|
||||
|
||||
static const struct soc_enum da732x_adc1_hp_filter_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||
DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_adc1_hp_filter_enum,
|
||||
DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||
da732x_hpf_music);
|
||||
|
||||
static const struct soc_enum da732x_adc2_hp_filter_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||
DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_adc2_hp_filter_enum,
|
||||
DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||
da732x_hpf_music);
|
||||
|
||||
static const struct soc_enum da732x_dac1_voice_filter_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||
DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_dac1_voice_filter_enum,
|
||||
DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||
da732x_hpf_voice);
|
||||
|
||||
static const struct soc_enum da732x_dac2_voice_filter_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||
DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_dac2_voice_filter_enum,
|
||||
DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||
da732x_hpf_voice);
|
||||
|
||||
static const struct soc_enum da732x_dac3_voice_filter_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||
DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_dac3_voice_filter_enum,
|
||||
DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||
da732x_hpf_voice);
|
||||
|
||||
static const struct soc_enum da732x_adc1_voice_filter_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||
DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
|
||||
};
|
||||
|
||||
static const struct soc_enum da732x_adc2_voice_filter_enum[] = {
|
||||
SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||
DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
|
||||
};
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_adc1_voice_filter_enum,
|
||||
DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||
da732x_hpf_voice);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_adc2_voice_filter_enum,
|
||||
DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||
da732x_hpf_voice);
|
||||
|
||||
static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
|
@ -714,65 +698,65 @@ static const char *enable_text[] = {
|
|||
};
|
||||
|
||||
/* ADC1LMUX */
|
||||
static const struct soc_enum adc1l_enum =
|
||||
SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT,
|
||||
DA732X_ADCL_MUX_MAX, adcl_text);
|
||||
static SOC_ENUM_SINGLE_DECL(adc1l_enum,
|
||||
DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT,
|
||||
adcl_text);
|
||||
static const struct snd_kcontrol_new adc1l_mux =
|
||||
SOC_DAPM_ENUM("ADC Route", adc1l_enum);
|
||||
|
||||
/* ADC1RMUX */
|
||||
static const struct soc_enum adc1r_enum =
|
||||
SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT,
|
||||
DA732X_ADCR_MUX_MAX, adcr_text);
|
||||
static SOC_ENUM_SINGLE_DECL(adc1r_enum,
|
||||
DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT,
|
||||
adcr_text);
|
||||
static const struct snd_kcontrol_new adc1r_mux =
|
||||
SOC_DAPM_ENUM("ADC Route", adc1r_enum);
|
||||
|
||||
/* ADC2LMUX */
|
||||
static const struct soc_enum adc2l_enum =
|
||||
SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT,
|
||||
DA732X_ADCL_MUX_MAX, adcl_text);
|
||||
static SOC_ENUM_SINGLE_DECL(adc2l_enum,
|
||||
DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT,
|
||||
adcl_text);
|
||||
static const struct snd_kcontrol_new adc2l_mux =
|
||||
SOC_DAPM_ENUM("ADC Route", adc2l_enum);
|
||||
|
||||
/* ADC2RMUX */
|
||||
static const struct soc_enum adc2r_enum =
|
||||
SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT,
|
||||
DA732X_ADCR_MUX_MAX, adcr_text);
|
||||
static SOC_ENUM_SINGLE_DECL(adc2r_enum,
|
||||
DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT,
|
||||
adcr_text);
|
||||
|
||||
static const struct snd_kcontrol_new adc2r_mux =
|
||||
SOC_DAPM_ENUM("ADC Route", adc2r_enum);
|
||||
|
||||
static const struct soc_enum da732x_hp_left_output =
|
||||
SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT,
|
||||
DA732X_DAC_EN_MAX, enable_text);
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_hp_left_output,
|
||||
DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT,
|
||||
enable_text);
|
||||
|
||||
static const struct snd_kcontrol_new hpl_mux =
|
||||
SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output);
|
||||
|
||||
static const struct soc_enum da732x_hp_right_output =
|
||||
SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT,
|
||||
DA732X_DAC_EN_MAX, enable_text);
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_hp_right_output,
|
||||
DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT,
|
||||
enable_text);
|
||||
|
||||
static const struct snd_kcontrol_new hpr_mux =
|
||||
SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output);
|
||||
|
||||
static const struct soc_enum da732x_speaker_output =
|
||||
SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT,
|
||||
DA732X_DAC_EN_MAX, enable_text);
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_speaker_output,
|
||||
DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT,
|
||||
enable_text);
|
||||
|
||||
static const struct snd_kcontrol_new spk_mux =
|
||||
SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output);
|
||||
|
||||
static const struct soc_enum da732x_lout4_output =
|
||||
SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT,
|
||||
DA732X_DAC_EN_MAX, enable_text);
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_lout4_output,
|
||||
DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT,
|
||||
enable_text);
|
||||
|
||||
static const struct snd_kcontrol_new lout4_mux =
|
||||
SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output);
|
||||
|
||||
static const struct soc_enum da732x_lout2_output =
|
||||
SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT,
|
||||
DA732X_DAC_EN_MAX, enable_text);
|
||||
static SOC_ENUM_SINGLE_DECL(da732x_lout2_output,
|
||||
DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT,
|
||||
enable_text);
|
||||
|
||||
static const struct snd_kcontrol_new lout2_mux =
|
||||
SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output);
|
||||
|
@ -1499,8 +1483,8 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
|
|||
|
||||
da732x_hp_dc_offset_cancellation(codec);
|
||||
|
||||
regcache_cache_only(codec->control_data, false);
|
||||
regcache_sync(codec->control_data);
|
||||
regcache_cache_only(da732x->regmap, false);
|
||||
regcache_sync(da732x->regmap);
|
||||
} else {
|
||||
snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
|
||||
DA732X_BIAS_BOOST_MASK,
|
||||
|
@ -1511,7 +1495,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
|
|||
}
|
||||
break;
|
||||
case SND_SOC_BIAS_OFF:
|
||||
regcache_cache_only(codec->control_data, true);
|
||||
regcache_cache_only(da732x->regmap, true);
|
||||
da732x_set_charge_pump(codec, DA732X_DISABLE_CP);
|
||||
snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
|
||||
DA732X_BIAS_DIS);
|
||||
|
@ -1566,7 +1550,6 @@ static struct snd_soc_codec_driver soc_codec_dev_da732x = {
|
|||
.dapm_routes = da732x_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes),
|
||||
.set_pll = da732x_set_dai_pll,
|
||||
.reg_cache_size = ARRAY_SIZE(da732x_reg_cache),
|
||||
};
|
||||
|
||||
static int da732x_i2c_probe(struct i2c_client *i2c,
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
|
@ -321,22 +323,22 @@ static const char * const da9055_hpf_cutoff_txt[] = {
|
|||
"Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_dac_hpf_cutoff =
|
||||
SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_dac_hpf_cutoff,
|
||||
DA9055_DAC_FILTERS1, 4, da9055_hpf_cutoff_txt);
|
||||
|
||||
static const struct soc_enum da9055_adc_hpf_cutoff =
|
||||
SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_adc_hpf_cutoff,
|
||||
DA9055_ADC_FILTERS1, 4, da9055_hpf_cutoff_txt);
|
||||
|
||||
/* ADC and DAC voice mode (8kHz) high pass cutoff value */
|
||||
static const char * const da9055_vf_cutoff_txt[] = {
|
||||
"2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_dac_vf_cutoff =
|
||||
SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 0, 8, da9055_vf_cutoff_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_dac_vf_cutoff,
|
||||
DA9055_DAC_FILTERS1, 0, da9055_vf_cutoff_txt);
|
||||
|
||||
static const struct soc_enum da9055_adc_vf_cutoff =
|
||||
SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 0, 8, da9055_vf_cutoff_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_adc_vf_cutoff,
|
||||
DA9055_ADC_FILTERS1, 0, da9055_vf_cutoff_txt);
|
||||
|
||||
/* Gain ramping rate value */
|
||||
static const char * const da9055_gain_ramping_txt[] = {
|
||||
|
@ -344,44 +346,44 @@ static const char * const da9055_gain_ramping_txt[] = {
|
|||
"nominal rate / 8"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_gain_ramping_rate =
|
||||
SOC_ENUM_SINGLE(DA9055_GAIN_RAMP_CTRL, 0, 4, da9055_gain_ramping_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_gain_ramping_rate,
|
||||
DA9055_GAIN_RAMP_CTRL, 0, da9055_gain_ramping_txt);
|
||||
|
||||
/* DAC noise gate setup time value */
|
||||
static const char * const da9055_dac_ng_setup_time_txt[] = {
|
||||
"256 samples", "512 samples", "1024 samples", "2048 samples"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_dac_ng_setup_time =
|
||||
SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 0, 4,
|
||||
da9055_dac_ng_setup_time_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_setup_time,
|
||||
DA9055_DAC_NG_SETUP_TIME, 0,
|
||||
da9055_dac_ng_setup_time_txt);
|
||||
|
||||
/* DAC noise gate rampup rate value */
|
||||
static const char * const da9055_dac_ng_rampup_txt[] = {
|
||||
"0.02 ms/dB", "0.16 ms/dB"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_dac_ng_rampup_rate =
|
||||
SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 2, 2,
|
||||
da9055_dac_ng_rampup_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_rampup_rate,
|
||||
DA9055_DAC_NG_SETUP_TIME, 2,
|
||||
da9055_dac_ng_rampup_txt);
|
||||
|
||||
/* DAC noise gate rampdown rate value */
|
||||
static const char * const da9055_dac_ng_rampdown_txt[] = {
|
||||
"0.64 ms/dB", "20.48 ms/dB"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_dac_ng_rampdown_rate =
|
||||
SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 3, 2,
|
||||
da9055_dac_ng_rampdown_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_rampdown_rate,
|
||||
DA9055_DAC_NG_SETUP_TIME, 3,
|
||||
da9055_dac_ng_rampdown_txt);
|
||||
|
||||
/* DAC soft mute rate value */
|
||||
static const char * const da9055_dac_soft_mute_rate_txt[] = {
|
||||
"1", "2", "4", "8", "16", "32", "64"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_dac_soft_mute_rate =
|
||||
SOC_ENUM_SINGLE(DA9055_DAC_FILTERS5, 4, 7,
|
||||
da9055_dac_soft_mute_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_dac_soft_mute_rate,
|
||||
DA9055_DAC_FILTERS5, 4,
|
||||
da9055_dac_soft_mute_rate_txt);
|
||||
|
||||
/* DAC routing select */
|
||||
static const char * const da9055_dac_src_txt[] = {
|
||||
|
@ -389,40 +391,40 @@ static const char * const da9055_dac_src_txt[] = {
|
|||
"AIF input right"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_dac_l_src =
|
||||
SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 0, 4, da9055_dac_src_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_dac_l_src,
|
||||
DA9055_DIG_ROUTING_DAC, 0, da9055_dac_src_txt);
|
||||
|
||||
static const struct soc_enum da9055_dac_r_src =
|
||||
SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 4, 4, da9055_dac_src_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_dac_r_src,
|
||||
DA9055_DIG_ROUTING_DAC, 4, da9055_dac_src_txt);
|
||||
|
||||
/* MIC PGA Left source select */
|
||||
static const char * const da9055_mic_l_src_txt[] = {
|
||||
"MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_mic_l_src =
|
||||
SOC_ENUM_SINGLE(DA9055_MIXIN_L_SELECT, 4, 4, da9055_mic_l_src_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_mic_l_src,
|
||||
DA9055_MIXIN_L_SELECT, 4, da9055_mic_l_src_txt);
|
||||
|
||||
/* MIC PGA Right source select */
|
||||
static const char * const da9055_mic_r_src_txt[] = {
|
||||
"MIC2_R_L", "MIC2_R", "MIC2_L"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_mic_r_src =
|
||||
SOC_ENUM_SINGLE(DA9055_MIXIN_R_SELECT, 4, 3, da9055_mic_r_src_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_mic_r_src,
|
||||
DA9055_MIXIN_R_SELECT, 4, da9055_mic_r_src_txt);
|
||||
|
||||
/* ALC Input Signal Tracking rate select */
|
||||
static const char * const da9055_signal_tracking_rate_txt[] = {
|
||||
"1/4", "1/16", "1/256", "1/65536"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_integ_attack_rate =
|
||||
SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 4, 4,
|
||||
da9055_signal_tracking_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_integ_attack_rate,
|
||||
DA9055_ALC_CTRL3, 4,
|
||||
da9055_signal_tracking_rate_txt);
|
||||
|
||||
static const struct soc_enum da9055_integ_release_rate =
|
||||
SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 6, 4,
|
||||
da9055_signal_tracking_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_integ_release_rate,
|
||||
DA9055_ALC_CTRL3, 6,
|
||||
da9055_signal_tracking_rate_txt);
|
||||
|
||||
/* ALC Attack Rate select */
|
||||
static const char * const da9055_attack_rate_txt[] = {
|
||||
|
@ -430,8 +432,8 @@ static const char * const da9055_attack_rate_txt[] = {
|
|||
"5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_attack_rate =
|
||||
SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 0, 13, da9055_attack_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_attack_rate,
|
||||
DA9055_ALC_CTRL2, 0, da9055_attack_rate_txt);
|
||||
|
||||
/* ALC Release Rate select */
|
||||
static const char * const da9055_release_rate_txt[] = {
|
||||
|
@ -439,8 +441,8 @@ static const char * const da9055_release_rate_txt[] = {
|
|||
"11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_release_rate =
|
||||
SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 4, 11, da9055_release_rate_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_release_rate,
|
||||
DA9055_ALC_CTRL2, 4, da9055_release_rate_txt);
|
||||
|
||||
/* ALC Hold Time select */
|
||||
static const char * const da9055_hold_time_txt[] = {
|
||||
|
@ -449,8 +451,8 @@ static const char * const da9055_hold_time_txt[] = {
|
|||
"253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
|
||||
};
|
||||
|
||||
static const struct soc_enum da9055_hold_time =
|
||||
SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 0, 16, da9055_hold_time_txt);
|
||||
static SOC_ENUM_SINGLE_DECL(da9055_hold_time,
|
||||
DA9055_ALC_CTRL3, 0, da9055_hold_time_txt);
|
||||
|
||||
static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
|
||||
{
|
||||
|
@ -1536,11 +1538,17 @@ static const struct i2c_device_id da9055_i2c_id[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
|
||||
|
||||
static const struct of_device_id da9055_of_match[] = {
|
||||
{ .compatible = "dlg,da9055-codec", },
|
||||
{ }
|
||||
};
|
||||
|
||||
/* I2C codec control layer */
|
||||
static struct i2c_driver da9055_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "da9055-codec",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(da9055_of_match),
|
||||
},
|
||||
.probe = da9055_i2c_probe,
|
||||
.remove = da9055_remove,
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* ALSA SoC TLV320AIC23 codec driver I2C interface
|
||||
*
|
||||
* Author: Arun KS, <arunks@mistralsolutions.com>
|
||||
* Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
|
||||
*
|
||||
* Based on sound/soc/codecs/wm8731.c by Richard Purdie
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "tlv320aic23.h"
|
||||
|
||||
static int tlv320aic23_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *i2c_id)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
|
||||
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return -EINVAL;
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap);
|
||||
return tlv320aic23_probe(&i2c->dev, regmap);
|
||||
}
|
||||
|
||||
static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
snd_soc_unregister_codec(&i2c->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tlv320aic23_id[] = {
|
||||
{"tlv320aic23", 0},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
|
||||
|
||||
static struct i2c_driver tlv320aic23_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "tlv320aic23-codec",
|
||||
},
|
||||
.probe = tlv320aic23_i2c_probe,
|
||||
.remove = __exit_p(tlv320aic23_i2c_remove),
|
||||
.id_table = tlv320aic23_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(tlv320aic23_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver I2C");
|
||||
MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* ALSA SoC TLV320AIC23 codec driver SPI interface
|
||||
*
|
||||
* Author: Arun KS, <arunks@mistralsolutions.com>
|
||||
* Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
|
||||
*
|
||||
* Based on sound/soc/codecs/wm8731.c by Richard Purdie
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "tlv320aic23.h"
|
||||
|
||||
static int aic23_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
int ret;
|
||||
struct regmap *regmap;
|
||||
|
||||
dev_dbg(&spi->dev, "probing tlv320aic23 spi device\n");
|
||||
|
||||
spi->bits_per_word = 16;
|
||||
spi->mode = SPI_MODE_0;
|
||||
ret = spi_setup(spi);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
regmap = devm_regmap_init_spi(spi, &tlv320aic23_regmap);
|
||||
return tlv320aic23_probe(&spi->dev, regmap);
|
||||
}
|
||||
|
||||
static int aic23_spi_remove(struct spi_device *spi)
|
||||
{
|
||||
snd_soc_unregister_codec(&spi->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_driver aic23_spi = {
|
||||
.driver = {
|
||||
.name = "tlv320aic23",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = aic23_spi_probe,
|
||||
.remove = aic23_spi_remove,
|
||||
};
|
||||
|
||||
module_spi_driver(aic23_spi);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver SPI");
|
||||
MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -23,7 +23,6 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <sound/core.h>
|
||||
|
@ -51,7 +50,7 @@ static const struct reg_default tlv320aic23_reg[] = {
|
|||
{ 9, 0x0000 },
|
||||
};
|
||||
|
||||
static const struct regmap_config tlv320aic23_regmap = {
|
||||
const struct regmap_config tlv320aic23_regmap = {
|
||||
.reg_bits = 7,
|
||||
.val_bits = 9,
|
||||
|
||||
|
@ -64,16 +63,16 @@ static const struct regmap_config tlv320aic23_regmap = {
|
|||
static const char *rec_src_text[] = { "Line", "Mic" };
|
||||
static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
|
||||
|
||||
static const struct soc_enum rec_src_enum =
|
||||
SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
|
||||
static SOC_ENUM_SINGLE_DECL(rec_src_enum,
|
||||
TLV320AIC23_ANLG, 2, rec_src_text);
|
||||
|
||||
static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
|
||||
SOC_DAPM_ENUM("Input Select", rec_src_enum);
|
||||
|
||||
static const struct soc_enum tlv320aic23_rec_src =
|
||||
SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
|
||||
static const struct soc_enum tlv320aic23_deemph =
|
||||
SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text);
|
||||
static SOC_ENUM_SINGLE_DECL(tlv320aic23_rec_src,
|
||||
TLV320AIC23_ANLG, 2, rec_src_text);
|
||||
static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph,
|
||||
TLV320AIC23_DIGT, 1, deemph_text);
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
|
||||
|
@ -557,7 +556,7 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tlv320aic23_probe(struct snd_soc_codec *codec)
|
||||
static int tlv320aic23_codec_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -604,7 +603,7 @@ static int tlv320aic23_remove(struct snd_soc_codec *codec)
|
|||
}
|
||||
|
||||
static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
|
||||
.probe = tlv320aic23_probe,
|
||||
.probe = tlv320aic23_codec_probe,
|
||||
.remove = tlv320aic23_remove,
|
||||
.suspend = tlv320aic23_suspend,
|
||||
.resume = tlv320aic23_resume,
|
||||
|
@ -617,56 +616,24 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
|
|||
.num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
|
||||
};
|
||||
|
||||
/*
|
||||
* If the i2c layer weren't so broken, we could pass this kind of data
|
||||
* around
|
||||
*/
|
||||
static int tlv320aic23_codec_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *i2c_id)
|
||||
int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
|
||||
{
|
||||
struct aic23 *aic23;
|
||||
int ret;
|
||||
|
||||
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return -EINVAL;
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
aic23 = devm_kzalloc(&i2c->dev, sizeof(struct aic23), GFP_KERNEL);
|
||||
aic23 = devm_kzalloc(dev, sizeof(struct aic23), GFP_KERNEL);
|
||||
if (aic23 == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
aic23->regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap);
|
||||
if (IS_ERR(aic23->regmap))
|
||||
return PTR_ERR(aic23->regmap);
|
||||
aic23->regmap = regmap;
|
||||
|
||||
i2c_set_clientdata(i2c, aic23);
|
||||
dev_set_drvdata(dev, aic23);
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
&soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1);
|
||||
return ret;
|
||||
return snd_soc_register_codec(dev, &soc_codec_dev_tlv320aic23,
|
||||
&tlv320aic23_dai, 1);
|
||||
}
|
||||
static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
snd_soc_unregister_codec(&i2c->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tlv320aic23_id[] = {
|
||||
{"tlv320aic23", 0},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
|
||||
|
||||
static struct i2c_driver tlv320aic23_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "tlv320aic23-codec",
|
||||
},
|
||||
.probe = tlv320aic23_codec_probe,
|
||||
.remove = __exit_p(tlv320aic23_i2c_remove),
|
||||
.id_table = tlv320aic23_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(tlv320aic23_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
|
||||
MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
|
||||
|
|
|
@ -12,6 +12,12 @@
|
|||
#ifndef _TLV320AIC23_H
|
||||
#define _TLV320AIC23_H
|
||||
|
||||
struct device;
|
||||
struct regmap_config;
|
||||
|
||||
extern const struct regmap_config tlv320aic23_regmap;
|
||||
int tlv320aic23_probe(struct device *dev, struct regmap *regmap);
|
||||
|
||||
/* Codec TLV320AIC23 */
|
||||
#define TLV320AIC23_LINVOL 0x00
|
||||
#define TLV320AIC23_RINVOL 0x01
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/platform_data/edma.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/clk.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
|
@ -30,9 +31,34 @@
|
|||
#include "davinci-i2s.h"
|
||||
|
||||
struct snd_soc_card_drvdata_davinci {
|
||||
struct clk *mclk;
|
||||
unsigned sysclk;
|
||||
};
|
||||
|
||||
static int evm_startup(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_card *soc_card = rtd->codec->card;
|
||||
struct snd_soc_card_drvdata_davinci *drvdata =
|
||||
snd_soc_card_get_drvdata(soc_card);
|
||||
|
||||
if (drvdata->mclk)
|
||||
return clk_prepare_enable(drvdata->mclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void evm_shutdown(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_card *soc_card = rtd->codec->card;
|
||||
struct snd_soc_card_drvdata_davinci *drvdata =
|
||||
snd_soc_card_get_drvdata(soc_card);
|
||||
|
||||
if (drvdata->mclk)
|
||||
clk_disable_unprepare(drvdata->mclk);
|
||||
}
|
||||
|
||||
static int evm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
|
@ -59,6 +85,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
|
|||
}
|
||||
|
||||
static struct snd_soc_ops evm_ops = {
|
||||
.startup = evm_startup,
|
||||
.shutdown = evm_shutdown,
|
||||
.hw_params = evm_hw_params,
|
||||
};
|
||||
|
||||
|
@ -348,6 +376,7 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
|||
of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
|
||||
struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data;
|
||||
struct snd_soc_card_drvdata_davinci *drvdata = NULL;
|
||||
struct clk *mclk;
|
||||
int ret = 0;
|
||||
|
||||
evm_soc_card.dai_link = dai;
|
||||
|
@ -367,13 +396,38 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
mclk = devm_clk_get(&pdev->dev, "mclk");
|
||||
if (PTR_ERR(mclk) == -EPROBE_DEFER) {
|
||||
return -EPROBE_DEFER;
|
||||
} else if (IS_ERR(mclk)) {
|
||||
dev_dbg(&pdev->dev, "mclk not found.\n");
|
||||
mclk = NULL;
|
||||
}
|
||||
|
||||
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
if (!drvdata)
|
||||
return -ENOMEM;
|
||||
|
||||
drvdata->mclk = mclk;
|
||||
|
||||
ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (ret < 0) {
|
||||
if (!drvdata->mclk) {
|
||||
dev_err(&pdev->dev,
|
||||
"No clock or clock rate defined.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
drvdata->sysclk = clk_get_rate(drvdata->mclk);
|
||||
} else if (drvdata->mclk) {
|
||||
unsigned int requestd_rate = drvdata->sysclk;
|
||||
clk_set_rate(drvdata->mclk, drvdata->sysclk);
|
||||
drvdata->sysclk = clk_get_rate(drvdata->mclk);
|
||||
if (drvdata->sysclk != requestd_rate)
|
||||
dev_warn(&pdev->dev,
|
||||
"Could not get requested rate %u using %u.\n",
|
||||
requestd_rate, drvdata->sysclk);
|
||||
}
|
||||
|
||||
snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
|
||||
ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
|
||||
|
|
|
@ -37,6 +37,16 @@
|
|||
#include "davinci-pcm.h"
|
||||
#include "davinci-mcasp.h"
|
||||
|
||||
struct davinci_mcasp_context {
|
||||
u32 txfmtctl;
|
||||
u32 rxfmtctl;
|
||||
u32 txfmt;
|
||||
u32 rxfmt;
|
||||
u32 aclkxctl;
|
||||
u32 aclkrctl;
|
||||
u32 pdir;
|
||||
};
|
||||
|
||||
struct davinci_mcasp {
|
||||
struct davinci_pcm_dma_params dma_params[2];
|
||||
struct snd_dmaengine_dai_dma_data dma_data[2];
|
||||
|
@ -53,6 +63,9 @@ struct davinci_mcasp {
|
|||
u16 bclk_lrclk_ratio;
|
||||
int streams;
|
||||
|
||||
int sysclk_freq;
|
||||
bool bclk_master;
|
||||
|
||||
/* McASP FIFO related */
|
||||
u8 txnumevt;
|
||||
u8 rxnumevt;
|
||||
|
@ -60,15 +73,7 @@ struct davinci_mcasp {
|
|||
bool dat_port;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
struct {
|
||||
u32 txfmtctl;
|
||||
u32 rxfmtctl;
|
||||
u32 txfmt;
|
||||
u32 rxfmt;
|
||||
u32 aclkxctl;
|
||||
u32 aclkrctl;
|
||||
u32 pdir;
|
||||
} context;
|
||||
struct davinci_mcasp_context context;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -294,6 +299,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
|
|||
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR);
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR);
|
||||
mcasp->bclk_master = 1;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBM_CFS:
|
||||
/* codec is clock master and frame slave */
|
||||
|
@ -305,6 +311,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
|
|||
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR);
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR);
|
||||
mcasp->bclk_master = 0;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBM_CFM:
|
||||
/* codec is clock and frame master */
|
||||
|
@ -316,6 +323,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
|
|||
|
||||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG,
|
||||
ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR);
|
||||
mcasp->bclk_master = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -410,6 +418,8 @@ static int davinci_mcasp_set_sysclk(struct snd_soc_dai *dai, int clk_id,
|
|||
mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX);
|
||||
}
|
||||
|
||||
mcasp->sysclk_freq = freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -603,20 +613,23 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
|
|||
u8 fifo_level;
|
||||
u8 slots = mcasp->tdm_slots;
|
||||
u8 active_serializers;
|
||||
int channels;
|
||||
int channels = params_channels(params);
|
||||
int ret;
|
||||
struct snd_interval *pcm_channels = hw_param_interval(params,
|
||||
SNDRV_PCM_HW_PARAM_CHANNELS);
|
||||
channels = pcm_channels->min;
|
||||
|
||||
active_serializers = (channels + slots - 1) / slots;
|
||||
/* If mcasp is BCLK master we need to set BCLK divider */
|
||||
if (mcasp->bclk_master) {
|
||||
unsigned int bclk_freq = snd_soc_params_to_bclk(params);
|
||||
if (mcasp->sysclk_freq % bclk_freq != 0) {
|
||||
dev_err(mcasp->dev, "Can't produce requred BCLK\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
davinci_mcasp_set_clkdiv(
|
||||
cpu_dai, 1, mcasp->sysclk_freq / bclk_freq);
|
||||
}
|
||||
|
||||
if (mcasp_common_hw_param(mcasp, substream->stream, channels) == -EINVAL)
|
||||
return -EINVAL;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
fifo_level = mcasp->txnumevt * active_serializers;
|
||||
else
|
||||
fifo_level = mcasp->rxnumevt * active_serializers;
|
||||
ret = mcasp_common_hw_param(mcasp, substream->stream, channels);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
|
||||
ret = mcasp_dit_hw_param(mcasp);
|
||||
|
@ -658,6 +671,13 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Calculate FIFO level */
|
||||
active_serializers = (channels + slots - 1) / slots;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
fifo_level = mcasp->txnumevt * active_serializers;
|
||||
else
|
||||
fifo_level = mcasp->rxnumevt * active_serializers;
|
||||
|
||||
if (mcasp->version == MCASP_VERSION_2 && !fifo_level)
|
||||
dma_params->acnt = 4;
|
||||
else
|
||||
|
@ -719,6 +739,43 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
|
|||
.set_sysclk = davinci_mcasp_set_sysclk,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int davinci_mcasp_suspend(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
|
||||
struct davinci_mcasp_context *context = &mcasp->context;
|
||||
|
||||
context->txfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG);
|
||||
context->rxfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG);
|
||||
context->txfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMT_REG);
|
||||
context->rxfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMT_REG);
|
||||
context->aclkxctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG);
|
||||
context->aclkrctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG);
|
||||
context->pdir = mcasp_get_reg(mcasp, DAVINCI_MCASP_PDIR_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int davinci_mcasp_resume(struct snd_soc_dai *dai)
|
||||
{
|
||||
struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);
|
||||
struct davinci_mcasp_context *context = &mcasp->context;
|
||||
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, context->txfmtctl);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG, context->rxfmtctl);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMT_REG, context->txfmt);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMT_REG, context->rxfmt);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, context->aclkxctl);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, context->aclkrctl);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_PDIR_REG, context->pdir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define davinci_mcasp_suspend NULL
|
||||
#define davinci_mcasp_resume NULL
|
||||
#endif
|
||||
|
||||
#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_192000
|
||||
|
||||
#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
|
||||
|
@ -735,6 +792,8 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
|
|||
static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
|
||||
{
|
||||
.name = "davinci-mcasp.0",
|
||||
.suspend = davinci_mcasp_suspend,
|
||||
.resume = davinci_mcasp_resume,
|
||||
.playback = {
|
||||
.channels_min = 2,
|
||||
.channels_max = 32 * 16,
|
||||
|
@ -768,28 +827,28 @@ static const struct snd_soc_component_driver davinci_mcasp_component = {
|
|||
};
|
||||
|
||||
/* Some HW specific values and defaults. The rest is filled in from DT. */
|
||||
static struct snd_platform_data dm646x_mcasp_pdata = {
|
||||
static struct davinci_mcasp_pdata dm646x_mcasp_pdata = {
|
||||
.tx_dma_offset = 0x400,
|
||||
.rx_dma_offset = 0x400,
|
||||
.asp_chan_q = EVENTQ_0,
|
||||
.version = MCASP_VERSION_1,
|
||||
};
|
||||
|
||||
static struct snd_platform_data da830_mcasp_pdata = {
|
||||
static struct davinci_mcasp_pdata da830_mcasp_pdata = {
|
||||
.tx_dma_offset = 0x2000,
|
||||
.rx_dma_offset = 0x2000,
|
||||
.asp_chan_q = EVENTQ_0,
|
||||
.version = MCASP_VERSION_2,
|
||||
};
|
||||
|
||||
static struct snd_platform_data am33xx_mcasp_pdata = {
|
||||
static struct davinci_mcasp_pdata am33xx_mcasp_pdata = {
|
||||
.tx_dma_offset = 0,
|
||||
.rx_dma_offset = 0,
|
||||
.asp_chan_q = EVENTQ_0,
|
||||
.version = MCASP_VERSION_3,
|
||||
};
|
||||
|
||||
static struct snd_platform_data dra7_mcasp_pdata = {
|
||||
static struct davinci_mcasp_pdata dra7_mcasp_pdata = {
|
||||
.tx_dma_offset = 0x200,
|
||||
.rx_dma_offset = 0x284,
|
||||
.asp_chan_q = EVENTQ_0,
|
||||
|
@ -857,11 +916,11 @@ err1:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
|
||||
static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of(
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct snd_platform_data *pdata = NULL;
|
||||
struct davinci_mcasp_pdata *pdata = NULL;
|
||||
const struct of_device_id *match =
|
||||
of_match_device(mcasp_dt_ids, &pdev->dev);
|
||||
struct of_phandle_args dma_spec;
|
||||
|
@ -874,7 +933,7 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
|
|||
pdata = pdev->dev.platform_data;
|
||||
return pdata;
|
||||
} else if (match) {
|
||||
pdata = (struct snd_platform_data *) match->data;
|
||||
pdata = (struct davinci_mcasp_pdata*) match->data;
|
||||
} else {
|
||||
/* control shouldn't reach here. something is wrong */
|
||||
ret = -EINVAL;
|
||||
|
@ -966,9 +1025,9 @@ nodata:
|
|||
|
||||
static int davinci_mcasp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct davinci_pcm_dma_params *dma_data;
|
||||
struct davinci_pcm_dma_params *dma_params;
|
||||
struct resource *mem, *ioarea, *res, *dat;
|
||||
struct snd_platform_data *pdata;
|
||||
struct davinci_mcasp_pdata *pdata;
|
||||
struct davinci_mcasp *mcasp;
|
||||
int ret;
|
||||
|
||||
|
@ -1035,41 +1094,41 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
|
|||
if (dat)
|
||||
mcasp->dat_port = true;
|
||||
|
||||
dma_data = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
|
||||
dma_data->asp_chan_q = pdata->asp_chan_q;
|
||||
dma_data->ram_chan_q = pdata->ram_chan_q;
|
||||
dma_data->sram_pool = pdata->sram_pool;
|
||||
dma_data->sram_size = pdata->sram_size_playback;
|
||||
dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
|
||||
dma_params->asp_chan_q = pdata->asp_chan_q;
|
||||
dma_params->ram_chan_q = pdata->ram_chan_q;
|
||||
dma_params->sram_pool = pdata->sram_pool;
|
||||
dma_params->sram_size = pdata->sram_size_playback;
|
||||
if (dat)
|
||||
dma_data->dma_addr = dat->start;
|
||||
dma_params->dma_addr = dat->start;
|
||||
else
|
||||
dma_data->dma_addr = mem->start + pdata->tx_dma_offset;
|
||||
dma_params->dma_addr = mem->start + pdata->tx_dma_offset;
|
||||
|
||||
/* Unconditional dmaengine stuff */
|
||||
mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_data->dma_addr;
|
||||
mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = dma_params->dma_addr;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
|
||||
if (res)
|
||||
dma_data->channel = res->start;
|
||||
dma_params->channel = res->start;
|
||||
else
|
||||
dma_data->channel = pdata->tx_dma_channel;
|
||||
dma_params->channel = pdata->tx_dma_channel;
|
||||
|
||||
dma_data = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE];
|
||||
dma_data->asp_chan_q = pdata->asp_chan_q;
|
||||
dma_data->ram_chan_q = pdata->ram_chan_q;
|
||||
dma_data->sram_pool = pdata->sram_pool;
|
||||
dma_data->sram_size = pdata->sram_size_capture;
|
||||
dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE];
|
||||
dma_params->asp_chan_q = pdata->asp_chan_q;
|
||||
dma_params->ram_chan_q = pdata->ram_chan_q;
|
||||
dma_params->sram_pool = pdata->sram_pool;
|
||||
dma_params->sram_size = pdata->sram_size_capture;
|
||||
if (dat)
|
||||
dma_data->dma_addr = dat->start;
|
||||
dma_params->dma_addr = dat->start;
|
||||
else
|
||||
dma_data->dma_addr = mem->start + pdata->rx_dma_offset;
|
||||
dma_params->dma_addr = mem->start + pdata->rx_dma_offset;
|
||||
|
||||
/* Unconditional dmaengine stuff */
|
||||
mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_data->dma_addr;
|
||||
mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = dma_params->dma_addr;
|
||||
|
||||
if (mcasp->version < MCASP_VERSION_3) {
|
||||
mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE;
|
||||
/* dma_data->dma_addr is pointing to the data port address */
|
||||
/* dma_params->dma_addr is pointing to the data port address */
|
||||
mcasp->dat_port = true;
|
||||
} else {
|
||||
mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE;
|
||||
|
@ -1077,9 +1136,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
|
|||
|
||||
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
|
||||
if (res)
|
||||
dma_data->channel = res->start;
|
||||
dma_params->channel = res->start;
|
||||
else
|
||||
dma_data->channel = pdata->rx_dma_channel;
|
||||
dma_params->channel = pdata->rx_dma_channel;
|
||||
|
||||
/* Unconditional dmaengine stuff */
|
||||
mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx";
|
||||
|
@ -1127,49 +1186,12 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int davinci_mcasp_suspend(struct device *dev)
|
||||
{
|
||||
struct davinci_mcasp *mcasp = dev_get_drvdata(dev);
|
||||
|
||||
mcasp->context.txfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG);
|
||||
mcasp->context.rxfmtctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG);
|
||||
mcasp->context.txfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_TXFMT_REG);
|
||||
mcasp->context.rxfmt = mcasp_get_reg(mcasp, DAVINCI_MCASP_RXFMT_REG);
|
||||
mcasp->context.aclkxctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG);
|
||||
mcasp->context.aclkrctl = mcasp_get_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG);
|
||||
mcasp->context.pdir = mcasp_get_reg(mcasp, DAVINCI_MCASP_PDIR_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int davinci_mcasp_resume(struct device *dev)
|
||||
{
|
||||
struct davinci_mcasp *mcasp = dev_get_drvdata(dev);
|
||||
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMCTL_REG, mcasp->context.txfmtctl);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMCTL_REG, mcasp->context.rxfmtctl);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_TXFMT_REG, mcasp->context.txfmt);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_RXFMT_REG, mcasp->context.rxfmt);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, mcasp->context.aclkxctl);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, mcasp->context.aclkrctl);
|
||||
mcasp_set_reg(mcasp, DAVINCI_MCASP_PDIR_REG, mcasp->context.pdir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
SIMPLE_DEV_PM_OPS(davinci_mcasp_pm_ops,
|
||||
davinci_mcasp_suspend,
|
||||
davinci_mcasp_resume);
|
||||
|
||||
static struct platform_driver davinci_mcasp_driver = {
|
||||
.probe = davinci_mcasp_probe,
|
||||
.remove = davinci_mcasp_remove,
|
||||
.driver = {
|
||||
.name = "davinci-mcasp",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &davinci_mcasp_pm_ops,
|
||||
.of_match_table = mcasp_dt_ids,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
config SND_SOC_FSL_SAI
|
||||
tristate
|
||||
select REGMAP_MMIO
|
||||
select SND_SOC_GENERIC_DMAENGINE_PCM
|
||||
|
||||
config SND_SOC_FSL_SSI
|
||||
|
@ -7,9 +8,11 @@ config SND_SOC_FSL_SSI
|
|||
|
||||
config SND_SOC_FSL_SPDIF
|
||||
tristate
|
||||
select REGMAP_MMIO
|
||||
|
||||
config SND_SOC_FSL_ESAI
|
||||
tristate
|
||||
select REGMAP_MMIO
|
||||
|
||||
config SND_SOC_FSL_UTILS
|
||||
tristate
|
||||
|
@ -168,12 +171,14 @@ config SND_SOC_EUKREA_TLV320
|
|||
depends on MACH_EUKREA_MBIMX27_BASEBOARD \
|
||||
|| MACH_EUKREA_MBIMXSD25_BASEBOARD \
|
||||
|| MACH_EUKREA_MBIMXSD35_BASEBOARD \
|
||||
|| MACH_EUKREA_MBIMXSD51_BASEBOARD
|
||||
|| MACH_EUKREA_MBIMXSD51_BASEBOARD \
|
||||
|| (OF && ARM)
|
||||
depends on I2C
|
||||
select SND_SOC_TLV320AIC23
|
||||
select SND_SOC_IMX_PCM_FIQ
|
||||
select SND_SOC_TLV320AIC23_I2C
|
||||
select SND_SOC_IMX_AUDMUX
|
||||
select SND_SOC_IMX_SSI
|
||||
select SND_SOC_FSL_SSI
|
||||
select SND_SOC_IMX_PCM_DMA
|
||||
help
|
||||
Enable I2S based access to the TLV320AIC23B codec attached
|
||||
to the SSI interface
|
||||
|
@ -204,7 +209,6 @@ config SND_SOC_IMX_SPDIF
|
|||
tristate "SoC Audio support for i.MX boards with S/PDIF"
|
||||
select SND_SOC_IMX_PCM_DMA
|
||||
select SND_SOC_FSL_SPDIF
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
SoC Audio support for i.MX boards with S/PDIF
|
||||
Say Y if you want to add support for SoC audio on an i.MX board with
|
||||
|
|
|
@ -15,8 +15,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <sound/core.h>
|
||||
|
@ -26,6 +29,7 @@
|
|||
|
||||
#include "../codecs/tlv320aic23.h"
|
||||
#include "imx-ssi.h"
|
||||
#include "fsl_ssi.h"
|
||||
#include "imx-audmux.h"
|
||||
|
||||
#define CODEC_CLOCK 12000000
|
||||
|
@ -41,7 +45,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
|
|||
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||
SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBM_CFM);
|
||||
if (ret) {
|
||||
/* fsl_ssi lacks the set_fmt ops. */
|
||||
if (ret && ret != -ENOTSUPP) {
|
||||
dev_err(cpu_dai->dev,
|
||||
"Failed to set the cpu dai format.\n");
|
||||
return ret;
|
||||
|
@ -63,11 +68,13 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
|
|||
"Failed to set the codec sysclk.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
|
||||
SND_SOC_CLOCK_IN);
|
||||
if (ret) {
|
||||
/* fsl_ssi lacks the set_sysclk ops */
|
||||
if (ret && ret != -EINVAL) {
|
||||
dev_err(cpu_dai->dev,
|
||||
"Can't set the IMX_SSP_SYS_CLK CPU system clock.\n");
|
||||
return ret;
|
||||
|
@ -84,14 +91,10 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = {
|
|||
.name = "tlv320aic23",
|
||||
.stream_name = "TLV320AIC23",
|
||||
.codec_dai_name = "tlv320aic23-hifi",
|
||||
.platform_name = "imx-ssi.0",
|
||||
.codec_name = "tlv320aic23-codec.0-001a",
|
||||
.cpu_dai_name = "imx-ssi.0",
|
||||
.ops = &eukrea_tlv320_snd_ops,
|
||||
};
|
||||
|
||||
static struct snd_soc_card eukrea_tlv320 = {
|
||||
.name = "cpuimx-audio",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = &eukrea_tlv320_dai,
|
||||
.num_links = 1,
|
||||
|
@ -101,8 +104,65 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
|
|||
{
|
||||
int ret;
|
||||
int int_port = 0, ext_port;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device_node *ssi_np, *codec_np;
|
||||
|
||||
if (machine_is_eukrea_cpuimx27()) {
|
||||
eukrea_tlv320.dev = &pdev->dev;
|
||||
if (np) {
|
||||
ret = snd_soc_of_parse_card_name(&eukrea_tlv320,
|
||||
"eukrea,model");
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"eukrea,model node missing or invalid.\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ssi_np = of_parse_phandle(pdev->dev.of_node,
|
||||
"ssi-controller", 0);
|
||||
if (!ssi_np) {
|
||||
dev_err(&pdev->dev,
|
||||
"ssi-controller missing or invalid.\n");
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
codec_np = of_parse_phandle(ssi_np, "codec-handle", 0);
|
||||
if (codec_np)
|
||||
eukrea_tlv320_dai.codec_of_node = codec_np;
|
||||
else
|
||||
dev_err(&pdev->dev, "codec-handle node missing or invalid.\n");
|
||||
|
||||
ret = of_property_read_u32(np, "fsl,mux-int-port", &int_port);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"fsl,mux-int-port node missing or invalid.\n");
|
||||
return ret;
|
||||
}
|
||||
ret = of_property_read_u32(np, "fsl,mux-ext-port", &ext_port);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"fsl,mux-ext-port node missing or invalid.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The port numbering in the hardware manual starts at 1, while
|
||||
* the audmux API expects it starts at 0.
|
||||
*/
|
||||
int_port--;
|
||||
ext_port--;
|
||||
|
||||
eukrea_tlv320_dai.cpu_of_node = ssi_np;
|
||||
eukrea_tlv320_dai.platform_of_node = ssi_np;
|
||||
} else {
|
||||
eukrea_tlv320_dai.cpu_dai_name = "imx-ssi.0";
|
||||
eukrea_tlv320_dai.platform_name = "imx-ssi.0";
|
||||
eukrea_tlv320_dai.codec_name = "tlv320aic23-codec.0-001a";
|
||||
eukrea_tlv320.name = "cpuimx-audio";
|
||||
}
|
||||
|
||||
if (machine_is_eukrea_cpuimx27() ||
|
||||
of_find_compatible_node(NULL, NULL, "fsl,imx21-audmux")) {
|
||||
imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
|
||||
IMX_AUDMUX_V1_PCR_SYN |
|
||||
IMX_AUDMUX_V1_PCR_TFSDIR |
|
||||
|
@ -119,8 +179,12 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
|
|||
);
|
||||
} else if (machine_is_eukrea_cpuimx25sd() ||
|
||||
machine_is_eukrea_cpuimx35sd() ||
|
||||
machine_is_eukrea_cpuimx51sd()) {
|
||||
ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3;
|
||||
machine_is_eukrea_cpuimx51sd() ||
|
||||
of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux")) {
|
||||
if (!np)
|
||||
ext_port = machine_is_eukrea_cpuimx25sd() ?
|
||||
4 : 3;
|
||||
|
||||
imx_audmux_v2_configure_port(int_port,
|
||||
IMX_AUDMUX_V2_PTCR_SYN |
|
||||
IMX_AUDMUX_V2_PTCR_TFSDIR |
|
||||
|
@ -134,14 +198,27 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
|
|||
IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)
|
||||
);
|
||||
} else {
|
||||
/* return happy. We might run on a totally different machine */
|
||||
return 0;
|
||||
if (np) {
|
||||
/* The eukrea,asoc-tlv320 driver was explicitely
|
||||
* requested (through the device tree).
|
||||
*/
|
||||
dev_err(&pdev->dev,
|
||||
"Missing or invalid audmux DT node.\n");
|
||||
return -ENODEV;
|
||||
} else {
|
||||
/* Return happy.
|
||||
* We might run on a totally different machine.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
eukrea_tlv320.dev = &pdev->dev;
|
||||
ret = snd_soc_register_card(&eukrea_tlv320);
|
||||
err:
|
||||
if (ret)
|
||||
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
|
||||
if (np)
|
||||
of_node_put(ssi_np);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -153,10 +230,17 @@ static int eukrea_tlv320_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id imx_tlv320_dt_ids[] = {
|
||||
{ .compatible = "eukrea,asoc-tlv320"},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx_tlv320_dt_ids);
|
||||
|
||||
static struct platform_driver eukrea_tlv320_driver = {
|
||||
.driver = {
|
||||
.name = "eukrea_tlv320",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = imx_tlv320_dt_ids,
|
||||
},
|
||||
.probe = eukrea_tlv320_probe,
|
||||
.remove = eukrea_tlv320_remove,
|
||||
|
|
|
@ -431,17 +431,26 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
|||
static int fsl_esai_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
int ret;
|
||||
struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
/*
|
||||
* Some platforms might use the same bit to gate all three or two of
|
||||
* clocks, so keep all clocks open/close at the same time for safety
|
||||
*/
|
||||
clk_prepare_enable(esai_priv->coreclk);
|
||||
if (!IS_ERR(esai_priv->extalclk))
|
||||
clk_prepare_enable(esai_priv->extalclk);
|
||||
if (!IS_ERR(esai_priv->fsysclk))
|
||||
clk_prepare_enable(esai_priv->fsysclk);
|
||||
ret = clk_prepare_enable(esai_priv->coreclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!IS_ERR(esai_priv->extalclk)) {
|
||||
ret = clk_prepare_enable(esai_priv->extalclk);
|
||||
if (ret)
|
||||
goto err_extalck;
|
||||
}
|
||||
if (!IS_ERR(esai_priv->fsysclk)) {
|
||||
ret = clk_prepare_enable(esai_priv->fsysclk);
|
||||
if (ret)
|
||||
goto err_fsysclk;
|
||||
}
|
||||
|
||||
if (!dai->active) {
|
||||
/* Reset Port C */
|
||||
|
@ -463,6 +472,14 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_fsysclk:
|
||||
if (!IS_ERR(esai_priv->extalclk))
|
||||
clk_disable_unprepare(esai_priv->extalclk);
|
||||
err_extalck:
|
||||
clk_disable_unprepare(esai_priv->coreclk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
|
||||
|
@ -661,7 +678,7 @@ static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
|
|||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config fsl_esai_regmap_config = {
|
||||
static struct regmap_config fsl_esai_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
|
@ -687,6 +704,9 @@ static int fsl_esai_probe(struct platform_device *pdev)
|
|||
esai_priv->pdev = pdev;
|
||||
strcpy(esai_priv->name, np->name);
|
||||
|
||||
if (of_property_read_bool(np, "big-endian"))
|
||||
fsl_esai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
|
||||
|
||||
/* Get the addresses and IRQ */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/dmaengine.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
@ -22,34 +23,6 @@
|
|||
|
||||
#include "fsl_sai.h"
|
||||
|
||||
static inline u32 sai_readl(struct fsl_sai *sai,
|
||||
const void __iomem *addr)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = __raw_readl(addr);
|
||||
|
||||
if (likely(sai->big_endian_regs))
|
||||
val = be32_to_cpu(val);
|
||||
else
|
||||
val = le32_to_cpu(val);
|
||||
rmb();
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void sai_writel(struct fsl_sai *sai,
|
||||
u32 val, void __iomem *addr)
|
||||
{
|
||||
wmb();
|
||||
if (likely(sai->big_endian_regs))
|
||||
val = cpu_to_be32(val);
|
||||
else
|
||||
val = cpu_to_le32(val);
|
||||
|
||||
__raw_writel(val, addr);
|
||||
}
|
||||
|
||||
static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
|
||||
int clk_id, unsigned int freq, int fsl_dir)
|
||||
{
|
||||
|
@ -61,7 +34,8 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
|
|||
else
|
||||
reg_cr2 = FSL_SAI_RCR2;
|
||||
|
||||
val_cr2 = sai_readl(sai, sai->base + reg_cr2);
|
||||
regmap_read(sai->regmap, reg_cr2, &val_cr2);
|
||||
|
||||
val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
|
||||
|
||||
switch (clk_id) {
|
||||
|
@ -81,7 +55,7 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
sai_writel(sai, val_cr2, sai->base + reg_cr2);
|
||||
regmap_write(sai->regmap, reg_cr2, val_cr2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -89,32 +63,22 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
|
|||
static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
|
||||
int clk_id, unsigned int freq, int dir)
|
||||
{
|
||||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
int ret;
|
||||
|
||||
if (dir == SND_SOC_CLOCK_IN)
|
||||
return 0;
|
||||
|
||||
ret = clk_prepare_enable(sai->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
|
||||
FSL_FMT_TRANSMITTER);
|
||||
if (ret) {
|
||||
dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret);
|
||||
goto err_clk;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
|
||||
FSL_FMT_RECEIVER);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret);
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
err_clk:
|
||||
clk_disable_unprepare(sai->clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -133,43 +97,84 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
|
|||
reg_cr4 = FSL_SAI_RCR4;
|
||||
}
|
||||
|
||||
val_cr2 = sai_readl(sai, sai->base + reg_cr2);
|
||||
val_cr4 = sai_readl(sai, sai->base + reg_cr4);
|
||||
regmap_read(sai->regmap, reg_cr2, &val_cr2);
|
||||
regmap_read(sai->regmap, reg_cr4, &val_cr4);
|
||||
|
||||
if (sai->big_endian_data)
|
||||
val_cr4 &= ~FSL_SAI_CR4_MF;
|
||||
else
|
||||
val_cr4 |= FSL_SAI_CR4_MF;
|
||||
|
||||
/* DAI mode */
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
val_cr4 |= FSL_SAI_CR4_FSE;
|
||||
/*
|
||||
* Frame low, 1clk before data, one word length for frame sync,
|
||||
* frame sync starts one serial clock cycle earlier,
|
||||
* that is, together with the last bit of the previous
|
||||
* data word.
|
||||
*/
|
||||
val_cr2 &= ~FSL_SAI_CR2_BCP;
|
||||
val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
/*
|
||||
* Frame high, one word length for frame sync,
|
||||
* frame sync asserts with the first bit of the frame.
|
||||
*/
|
||||
val_cr2 &= ~FSL_SAI_CR2_BCP;
|
||||
val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP);
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
/*
|
||||
* Frame high, 1clk before data, one bit for frame sync,
|
||||
* frame sync starts one serial clock cycle earlier,
|
||||
* that is, together with the last bit of the previous
|
||||
* data word.
|
||||
*/
|
||||
val_cr2 &= ~FSL_SAI_CR2_BCP;
|
||||
val_cr4 &= ~FSL_SAI_CR4_FSP;
|
||||
val_cr4 |= FSL_SAI_CR4_FSE;
|
||||
sai->is_dsp_mode = true;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
/*
|
||||
* Frame high, one bit for frame sync,
|
||||
* frame sync asserts with the first bit of the frame.
|
||||
*/
|
||||
val_cr2 &= ~FSL_SAI_CR2_BCP;
|
||||
val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP);
|
||||
sai->is_dsp_mode = true;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_RIGHT_J:
|
||||
/* To be done */
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* DAI clock inversion */
|
||||
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||
case SND_SOC_DAIFMT_IB_IF:
|
||||
val_cr4 |= FSL_SAI_CR4_FSP;
|
||||
val_cr2 &= ~FSL_SAI_CR2_BCP;
|
||||
/* Invert both clocks */
|
||||
val_cr2 ^= FSL_SAI_CR2_BCP;
|
||||
val_cr4 ^= FSL_SAI_CR4_FSP;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_IB_NF:
|
||||
val_cr4 &= ~FSL_SAI_CR4_FSP;
|
||||
val_cr2 &= ~FSL_SAI_CR2_BCP;
|
||||
/* Invert bit clock */
|
||||
val_cr2 ^= FSL_SAI_CR2_BCP;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_NB_IF:
|
||||
val_cr4 |= FSL_SAI_CR4_FSP;
|
||||
val_cr2 |= FSL_SAI_CR2_BCP;
|
||||
/* Invert frame clock */
|
||||
val_cr4 ^= FSL_SAI_CR4_FSP;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_NB_NF:
|
||||
val_cr4 &= ~FSL_SAI_CR4_FSP;
|
||||
val_cr2 |= FSL_SAI_CR2_BCP;
|
||||
/* Nothing to do for both normal cases */
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* DAI clock master masks */
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
|
||||
|
@ -179,39 +184,37 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
|
|||
val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR;
|
||||
val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBS_CFM:
|
||||
val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
|
||||
val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_CBM_CFS:
|
||||
val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR;
|
||||
val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sai_writel(sai, val_cr2, sai->base + reg_cr2);
|
||||
sai_writel(sai, val_cr4, sai->base + reg_cr4);
|
||||
regmap_write(sai->regmap, reg_cr2, val_cr2);
|
||||
regmap_write(sai->regmap, reg_cr4, val_cr4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
|
||||
{
|
||||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(sai->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER);
|
||||
if (ret) {
|
||||
dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret);
|
||||
goto err_clk;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret);
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
err_clk:
|
||||
clk_disable_unprepare(sai->clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -235,16 +238,19 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
|
|||
reg_mr = FSL_SAI_RMR;
|
||||
}
|
||||
|
||||
val_cr4 = sai_readl(sai, sai->base + reg_cr4);
|
||||
regmap_read(sai->regmap, reg_cr4, &val_cr4);
|
||||
regmap_read(sai->regmap, reg_cr4, &val_cr5);
|
||||
|
||||
val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK;
|
||||
val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK;
|
||||
|
||||
val_cr5 = sai_readl(sai, sai->base + reg_cr5);
|
||||
val_cr5 &= ~FSL_SAI_CR5_WNW_MASK;
|
||||
val_cr5 &= ~FSL_SAI_CR5_W0W_MASK;
|
||||
val_cr5 &= ~FSL_SAI_CR5_FBT_MASK;
|
||||
|
||||
val_cr4 |= FSL_SAI_CR4_SYWD(word_width);
|
||||
if (!sai->is_dsp_mode)
|
||||
val_cr4 |= FSL_SAI_CR4_SYWD(word_width);
|
||||
|
||||
val_cr5 |= FSL_SAI_CR5_WNW(word_width);
|
||||
val_cr5 |= FSL_SAI_CR5_W0W(word_width);
|
||||
|
||||
|
@ -257,9 +263,9 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
|
|||
val_cr4 |= FSL_SAI_CR4_FRSZ(channels);
|
||||
val_mr = ~0UL - ((1 << channels) - 1);
|
||||
|
||||
sai_writel(sai, val_cr4, sai->base + reg_cr4);
|
||||
sai_writel(sai, val_cr5, sai->base + reg_cr5);
|
||||
sai_writel(sai, val_mr, sai->base + reg_mr);
|
||||
regmap_write(sai->regmap, reg_cr4, val_cr4);
|
||||
regmap_write(sai->regmap, reg_cr5, val_cr5);
|
||||
regmap_write(sai->regmap, reg_mr, val_mr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -268,44 +274,42 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
u32 tcsr, rcsr, val_cr2, val_cr3, reg_cr3;
|
||||
u32 tcsr, rcsr;
|
||||
|
||||
val_cr2 = sai_readl(sai, sai->base + FSL_SAI_TCR2);
|
||||
val_cr2 &= ~FSL_SAI_CR2_SYNC;
|
||||
sai_writel(sai, val_cr2, sai->base + FSL_SAI_TCR2);
|
||||
/*
|
||||
* The transmitter bit clock and frame sync are to be
|
||||
* used by both the transmitter and receiver.
|
||||
*/
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
|
||||
~FSL_SAI_CR2_SYNC);
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
|
||||
FSL_SAI_CR2_SYNC);
|
||||
|
||||
val_cr2 = sai_readl(sai, sai->base + FSL_SAI_RCR2);
|
||||
val_cr2 |= FSL_SAI_CR2_SYNC;
|
||||
sai_writel(sai, val_cr2, sai->base + FSL_SAI_RCR2);
|
||||
|
||||
tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR);
|
||||
rcsr = sai_readl(sai, sai->base + FSL_SAI_RCSR);
|
||||
regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr);
|
||||
regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
tcsr |= FSL_SAI_CSR_FRDE;
|
||||
rcsr &= ~FSL_SAI_CSR_FRDE;
|
||||
reg_cr3 = FSL_SAI_TCR3;
|
||||
} else {
|
||||
rcsr |= FSL_SAI_CSR_FRDE;
|
||||
tcsr &= ~FSL_SAI_CSR_FRDE;
|
||||
reg_cr3 = FSL_SAI_RCR3;
|
||||
}
|
||||
|
||||
val_cr3 = sai_readl(sai, sai->base + reg_cr3);
|
||||
|
||||
/*
|
||||
* It is recommended that the transmitter is the last enabled
|
||||
* and the first disabled.
|
||||
*/
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
tcsr |= FSL_SAI_CSR_TERE;
|
||||
rcsr |= FSL_SAI_CSR_TERE;
|
||||
val_cr3 |= FSL_SAI_CR3_TRCE;
|
||||
|
||||
sai_writel(sai, val_cr3, sai->base + reg_cr3);
|
||||
sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR);
|
||||
sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR);
|
||||
regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr);
|
||||
regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr);
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
|
@ -314,11 +318,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
rcsr &= ~FSL_SAI_CSR_TERE;
|
||||
}
|
||||
|
||||
val_cr3 &= ~FSL_SAI_CR3_TRCE;
|
||||
|
||||
sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR);
|
||||
sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR);
|
||||
sai_writel(sai, val_cr3, sai->base + reg_cr3);
|
||||
regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr);
|
||||
regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -331,16 +332,32 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
u32 reg;
|
||||
|
||||
return clk_prepare_enable(sai->clk);
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
reg = FSL_SAI_TCR3;
|
||||
else
|
||||
reg = FSL_SAI_RCR3;
|
||||
|
||||
regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE,
|
||||
FSL_SAI_CR3_TRCE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
u32 reg;
|
||||
|
||||
clk_disable_unprepare(sai->clk);
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
reg = FSL_SAI_TCR3;
|
||||
else
|
||||
reg = FSL_SAI_RCR3;
|
||||
|
||||
regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE,
|
||||
~FSL_SAI_CR3_TRCE);
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
|
||||
|
@ -355,18 +372,13 @@ static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
|
|||
static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
|
||||
{
|
||||
struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(sai->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sai_writel(sai, 0x0, sai->base + FSL_SAI_RCSR);
|
||||
sai_writel(sai, 0x0, sai->base + FSL_SAI_TCSR);
|
||||
sai_writel(sai, FSL_SAI_MAXBURST_TX * 2, sai->base + FSL_SAI_TCR1);
|
||||
sai_writel(sai, FSL_SAI_MAXBURST_RX - 1, sai->base + FSL_SAI_RCR1);
|
||||
|
||||
clk_disable_unprepare(sai->clk);
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0);
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0);
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
|
||||
FSL_SAI_MAXBURST_TX * 2);
|
||||
regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
|
||||
FSL_SAI_MAXBURST_RX - 1);
|
||||
|
||||
snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
|
||||
&sai->dma_params_rx);
|
||||
|
@ -397,26 +409,109 @@ static const struct snd_soc_component_driver fsl_component = {
|
|||
.name = "fsl-sai",
|
||||
};
|
||||
|
||||
static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case FSL_SAI_TCSR:
|
||||
case FSL_SAI_TCR1:
|
||||
case FSL_SAI_TCR2:
|
||||
case FSL_SAI_TCR3:
|
||||
case FSL_SAI_TCR4:
|
||||
case FSL_SAI_TCR5:
|
||||
case FSL_SAI_TFR:
|
||||
case FSL_SAI_TMR:
|
||||
case FSL_SAI_RCSR:
|
||||
case FSL_SAI_RCR1:
|
||||
case FSL_SAI_RCR2:
|
||||
case FSL_SAI_RCR3:
|
||||
case FSL_SAI_RCR4:
|
||||
case FSL_SAI_RCR5:
|
||||
case FSL_SAI_RDR:
|
||||
case FSL_SAI_RFR:
|
||||
case FSL_SAI_RMR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case FSL_SAI_TFR:
|
||||
case FSL_SAI_RFR:
|
||||
case FSL_SAI_TDR:
|
||||
case FSL_SAI_RDR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case FSL_SAI_TCSR:
|
||||
case FSL_SAI_TCR1:
|
||||
case FSL_SAI_TCR2:
|
||||
case FSL_SAI_TCR3:
|
||||
case FSL_SAI_TCR4:
|
||||
case FSL_SAI_TCR5:
|
||||
case FSL_SAI_TDR:
|
||||
case FSL_SAI_TMR:
|
||||
case FSL_SAI_RCSR:
|
||||
case FSL_SAI_RCR1:
|
||||
case FSL_SAI_RCR2:
|
||||
case FSL_SAI_RCR3:
|
||||
case FSL_SAI_RCR4:
|
||||
case FSL_SAI_RCR5:
|
||||
case FSL_SAI_RMR:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static struct regmap_config fsl_sai_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
|
||||
.max_register = FSL_SAI_RMR,
|
||||
.readable_reg = fsl_sai_readable_reg,
|
||||
.volatile_reg = fsl_sai_volatile_reg,
|
||||
.writeable_reg = fsl_sai_writeable_reg,
|
||||
};
|
||||
|
||||
static int fsl_sai_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct fsl_sai *sai;
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
|
||||
if (!sai)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
sai->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(sai->base))
|
||||
return PTR_ERR(sai->base);
|
||||
sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
|
||||
if (sai->big_endian_regs)
|
||||
fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
|
||||
|
||||
sai->clk = devm_clk_get(&pdev->dev, "sai");
|
||||
if (IS_ERR(sai->clk)) {
|
||||
dev_err(&pdev->dev, "Cannot get SAI's clock\n");
|
||||
return PTR_ERR(sai->clk);
|
||||
sai->big_endian_data = of_property_read_bool(np, "big-endian-data");
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
|
||||
"sai", base, &fsl_sai_regmap_config);
|
||||
if (IS_ERR(sai->regmap)) {
|
||||
dev_err(&pdev->dev, "regmap init failed\n");
|
||||
return PTR_ERR(sai->regmap);
|
||||
}
|
||||
|
||||
sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
|
||||
|
@ -424,9 +519,6 @@ static int fsl_sai_probe(struct platform_device *pdev)
|
|||
sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
|
||||
sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
|
||||
|
||||
sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
|
||||
sai->big_endian_data = of_property_read_bool(np, "big-endian-data");
|
||||
|
||||
platform_set_drvdata(pdev, sai);
|
||||
|
||||
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
|
||||
|
|
|
@ -15,31 +15,36 @@
|
|||
SNDRV_PCM_FMTBIT_S20_3LE |\
|
||||
SNDRV_PCM_FMTBIT_S24_LE)
|
||||
|
||||
/* SAI Register Map Register */
|
||||
#define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */
|
||||
#define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */
|
||||
#define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */
|
||||
#define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */
|
||||
#define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */
|
||||
#define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */
|
||||
#define FSL_SAI_TDR 0x20 /* SAI Transmit Data */
|
||||
#define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */
|
||||
#define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */
|
||||
#define FSL_SAI_RCSR 0x80 /* SAI Receive Control */
|
||||
#define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */
|
||||
#define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */
|
||||
#define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */
|
||||
#define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */
|
||||
#define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */
|
||||
#define FSL_SAI_RDR 0xa0 /* SAI Receive Data */
|
||||
#define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */
|
||||
#define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */
|
||||
|
||||
/* SAI Transmit/Recieve Control Register */
|
||||
#define FSL_SAI_TCSR 0x00
|
||||
#define FSL_SAI_RCSR 0x80
|
||||
#define FSL_SAI_CSR_TERE BIT(31)
|
||||
#define FSL_SAI_CSR_FWF BIT(17)
|
||||
#define FSL_SAI_CSR_FRIE BIT(8)
|
||||
#define FSL_SAI_CSR_FRDE BIT(0)
|
||||
|
||||
/* SAI Transmit Data/FIFO/MASK Register */
|
||||
#define FSL_SAI_TDR 0x20
|
||||
#define FSL_SAI_TFR 0x40
|
||||
#define FSL_SAI_TMR 0x60
|
||||
|
||||
/* SAI Recieve Data/FIFO/MASK Register */
|
||||
#define FSL_SAI_RDR 0xa0
|
||||
#define FSL_SAI_RFR 0xc0
|
||||
#define FSL_SAI_RMR 0xe0
|
||||
|
||||
/* SAI Transmit and Recieve Configuration 1 Register */
|
||||
#define FSL_SAI_TCR1 0x04
|
||||
#define FSL_SAI_RCR1 0x84
|
||||
#define FSL_SAI_CR1_RFW_MASK 0x1f
|
||||
|
||||
/* SAI Transmit and Recieve Configuration 2 Register */
|
||||
#define FSL_SAI_TCR2 0x08
|
||||
#define FSL_SAI_RCR2 0x88
|
||||
#define FSL_SAI_CR2_SYNC BIT(30)
|
||||
#define FSL_SAI_CR2_MSEL_MASK (0xff << 26)
|
||||
#define FSL_SAI_CR2_MSEL_BUS 0
|
||||
|
@ -50,15 +55,11 @@
|
|||
#define FSL_SAI_CR2_BCD_MSTR BIT(24)
|
||||
|
||||
/* SAI Transmit and Recieve Configuration 3 Register */
|
||||
#define FSL_SAI_TCR3 0x0c
|
||||
#define FSL_SAI_RCR3 0x8c
|
||||
#define FSL_SAI_CR3_TRCE BIT(16)
|
||||
#define FSL_SAI_CR3_WDFL(x) (x)
|
||||
#define FSL_SAI_CR3_WDFL_MASK 0x1f
|
||||
|
||||
/* SAI Transmit and Recieve Configuration 4 Register */
|
||||
#define FSL_SAI_TCR4 0x10
|
||||
#define FSL_SAI_RCR4 0x90
|
||||
#define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16)
|
||||
#define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16)
|
||||
#define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8)
|
||||
|
@ -69,8 +70,6 @@
|
|||
#define FSL_SAI_CR4_FSD_MSTR BIT(0)
|
||||
|
||||
/* SAI Transmit and Recieve Configuration 5 Register */
|
||||
#define FSL_SAI_TCR5 0x14
|
||||
#define FSL_SAI_RCR5 0x94
|
||||
#define FSL_SAI_CR5_WNW(x) (((x) - 1) << 24)
|
||||
#define FSL_SAI_CR5_WNW_MASK (0x1f << 24)
|
||||
#define FSL_SAI_CR5_W0W(x) (((x) - 1) << 16)
|
||||
|
@ -100,12 +99,11 @@
|
|||
#define FSL_SAI_MAXBURST_RX 6
|
||||
|
||||
struct fsl_sai {
|
||||
struct clk *clk;
|
||||
|
||||
void __iomem *base;
|
||||
struct regmap *regmap;
|
||||
|
||||
bool big_endian_regs;
|
||||
bool big_endian_data;
|
||||
bool is_dsp_mode;
|
||||
|
||||
struct snd_dmaengine_dai_dma_data dma_params_rx;
|
||||
struct snd_dmaengine_dai_dma_data dma_params_tx;
|
||||
|
|
|
@ -911,8 +911,8 @@ static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
|
|||
{
|
||||
struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai);
|
||||
|
||||
dai->playback_dma_data = &spdif_private->dma_params_tx;
|
||||
dai->capture_dma_data = &spdif_private->dma_params_rx;
|
||||
snd_soc_dai_init_dma_data(dai, &spdif_private->dma_params_tx,
|
||||
&spdif_private->dma_params_rx);
|
||||
|
||||
snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls));
|
||||
|
||||
|
@ -985,7 +985,7 @@ static bool fsl_spdif_writeable_reg(struct device *dev, unsigned int reg)
|
|||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config fsl_spdif_regmap_config = {
|
||||
static struct regmap_config fsl_spdif_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
|
@ -1105,6 +1105,9 @@ static int fsl_spdif_probe(struct platform_device *pdev)
|
|||
memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai));
|
||||
spdif_priv->cpu_dai_drv.name = spdif_priv->name;
|
||||
|
||||
if (of_property_read_bool(np, "big-endian"))
|
||||
fsl_spdif_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
|
||||
|
||||
/* Get the addresses and IRQ */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
|
|
|
@ -270,18 +270,17 @@ static int imx_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
|||
ret = imx_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_PLAYBACK);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
|
||||
ret = imx_pcm_preallocate_dma_buffer(pcm,
|
||||
SNDRV_PCM_STREAM_CAPTURE);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ssi_irq = 0;
|
||||
|
|
|
@ -214,12 +214,6 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
|
|||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
|
||||
snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets,
|
||||
ARRAY_SIZE(wm1133_ev1_widgets));
|
||||
|
||||
snd_soc_dapm_add_routes(dapm, wm1133_ev1_map,
|
||||
ARRAY_SIZE(wm1133_ev1_map));
|
||||
|
||||
/* Headphone jack detection */
|
||||
snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
|
||||
snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
|
||||
|
@ -257,6 +251,11 @@ static struct snd_soc_card wm1133_ev1 = {
|
|||
.owner = THIS_MODULE,
|
||||
.dai_link = &wm1133_ev1_dai,
|
||||
.num_links = 1,
|
||||
|
||||
.dapm_widgets = wm1133_ev1_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(wm1133_ev1_widgets),
|
||||
.dapm_routes = wm1133_ev1_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(wm1133_ev1_map),
|
||||
};
|
||||
|
||||
static struct platform_device *wm1133_ev1_snd_device;
|
||||
|
|
|
@ -58,7 +58,7 @@ config SND_OMAP_SOC_OSK5912
|
|||
tristate "SoC Audio support for omap osk5912"
|
||||
depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C
|
||||
select SND_OMAP_SOC_MCBSP
|
||||
select SND_SOC_TLV320AIC23
|
||||
select SND_SOC_TLV320AIC23_I2C
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on osk5912.
|
||||
|
||||
|
@ -66,7 +66,7 @@ config SND_OMAP_SOC_AM3517EVM
|
|||
tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
|
||||
depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
|
||||
select SND_OMAP_SOC_MCBSP
|
||||
select SND_SOC_TLV320AIC23
|
||||
select SND_SOC_TLV320AIC23_I2C
|
||||
help
|
||||
Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
|
||||
EVM.
|
||||
|
|
|
@ -117,7 +117,7 @@ config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23
|
|||
tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
|
||||
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
|
||||
select SND_S3C24XX_I2S
|
||||
select SND_SOC_TLV320AIC23
|
||||
select SND_SOC_TLV320AIC23_I2C
|
||||
select SND_SOC_SAMSUNG_SIMTEC
|
||||
|
||||
config SND_SOC_SAMSUNG_SIMTEC_HERMES
|
||||
|
|
|
@ -105,7 +105,7 @@ config SND_SOC_TEGRA_TRIMSLICE
|
|||
tristate "SoC Audio support for TrimSlice board"
|
||||
depends on SND_SOC_TEGRA && I2C
|
||||
select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
|
||||
select SND_SOC_TLV320AIC23
|
||||
select SND_SOC_TLV320AIC23_I2C
|
||||
help
|
||||
Say Y or M here if you want to add support for SoC audio on the
|
||||
TrimSlice platform.
|
||||
|
|
Loading…
Reference in New Issue