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
30 changed files with 973 additions and 534 deletions
22
Documentation/devicetree/bindings/sound/da9055.txt
Normal file
22
Documentation/devicetree/bindings/sound/da9055.txt
Normal file
|
|
@ -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,model : The user-visible name of this sound complex.
|
||||||
- ti,audio-codec : The phandle of the TLV320AIC3x audio codec
|
- ti,audio-codec : The phandle of the TLV320AIC3x audio codec
|
||||||
- ti,mcasp-controller : The phandle of the McASP controller
|
- 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.
|
- 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,
|
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
|
the second being the connection's source. Valid names for sources and
|
||||||
sinks are the codec's pins, and the jacks on the board:
|
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:
|
Board connectors:
|
||||||
|
|
||||||
* Headphone Jack
|
* Headphone Jack
|
||||||
|
|
|
||||||
21
Documentation/devicetree/bindings/sound/eukrea-tlv320.txt
Normal file
21
Documentation/devicetree/bindings/sound/eukrea-tlv320.txt
Normal file
|
|
@ -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
|
that ESAI would work in the synchronous mode, which means all the settings
|
||||||
for Receiving would be duplicated from Transmition related registers.
|
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:
|
Example:
|
||||||
|
|
||||||
esai: esai@02024000 {
|
esai: esai@02024000 {
|
||||||
|
|
@ -46,5 +50,6 @@ esai: esai@02024000 {
|
||||||
dma-names = "rx", "tx";
|
dma-names = "rx", "tx";
|
||||||
fsl,fifo-depth = <128>;
|
fsl,fifo-depth = <128>;
|
||||||
fsl,esai-synchronous;
|
fsl,esai-synchronous;
|
||||||
|
big-endian;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,10 @@ Required properties:
|
||||||
can also be referred to TxClk_Source
|
can also be referred to TxClk_Source
|
||||||
bit of register SPDIF_STC.
|
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:
|
Example:
|
||||||
|
|
||||||
spdif: spdif@02004000 {
|
spdif: spdif@02004000 {
|
||||||
|
|
@ -50,5 +54,6 @@ spdif: spdif@02004000 {
|
||||||
"rxtx5", "rxtx6",
|
"rxtx5", "rxtx6",
|
||||||
"rxtx7";
|
"rxtx7";
|
||||||
|
|
||||||
|
big-endian;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
#include <linux/genalloc.h>
|
#include <linux/genalloc.h>
|
||||||
|
|
||||||
struct snd_platform_data {
|
struct davinci_mcasp_pdata {
|
||||||
u32 tx_dma_offset;
|
u32 tx_dma_offset;
|
||||||
u32 rx_dma_offset;
|
u32 rx_dma_offset;
|
||||||
int asp_chan_q; /* event queue number for ASP channel */
|
int asp_chan_q; /* event queue number for ASP channel */
|
||||||
|
|
@ -87,6 +87,8 @@ struct snd_platform_data {
|
||||||
int tx_dma_channel;
|
int tx_dma_channel;
|
||||||
int rx_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 {
|
enum {
|
||||||
MCASP_VERSION_1 = 0, /* DM646x */
|
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
|
depends on ARCH_AT91 && ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC
|
||||||
select SND_ATMEL_SOC_PDC
|
select SND_ATMEL_SOC_PDC
|
||||||
select SND_ATMEL_SOC_SSC
|
select SND_ATMEL_SOC_SSC
|
||||||
select SND_SOC_TLV320AIC23
|
select SND_SOC_TLV320AIC23_I2C
|
||||||
help
|
help
|
||||||
Say Y here to support sound on AFEB9260 board.
|
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"
|
tristate "SoC Audio support for Bluewater Systems Snapper CL15 module"
|
||||||
depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15
|
depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15
|
||||||
select SND_EP93XX_SOC_I2S
|
select SND_EP93XX_SOC_I2S
|
||||||
select SND_SOC_TLV320AIC23
|
select SND_SOC_TLV320AIC23_I2C
|
||||||
help
|
help
|
||||||
Say Y or M here if you want to add support for I2S audio on the
|
Say Y or M here if you want to add support for I2S audio on the
|
||||||
Bluewater Systems Snapper CL15 module.
|
Bluewater Systems Snapper CL15 module.
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,8 @@ config SND_SOC_ALL_CODECS
|
||||||
select SND_SOC_STA529 if I2C
|
select SND_SOC_STA529 if I2C
|
||||||
select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
|
select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
|
||||||
select SND_SOC_TAS5086 if I2C
|
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_TLV320AIC26 if SPI_MASTER
|
||||||
select SND_SOC_TLV320AIC32X4 if I2C
|
select SND_SOC_TLV320AIC32X4 if I2C
|
||||||
select SND_SOC_TLV320AIC3X if I2C
|
select SND_SOC_TLV320AIC3X if I2C
|
||||||
|
|
@ -422,6 +423,14 @@ config SND_SOC_TAS5086
|
||||||
config SND_SOC_TLV320AIC23
|
config SND_SOC_TLV320AIC23
|
||||||
tristate
|
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
|
config SND_SOC_TLV320AIC26
|
||||||
tristate
|
tristate
|
||||||
depends on SPI
|
depends on SPI
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,8 @@ snd-soc-sta529-objs := sta529.o
|
||||||
snd-soc-stac9766-objs := stac9766.o
|
snd-soc-stac9766-objs := stac9766.o
|
||||||
snd-soc-tas5086-objs := tas5086.o
|
snd-soc-tas5086-objs := tas5086.o
|
||||||
snd-soc-tlv320aic23-objs := tlv320aic23.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-tlv320aic26-objs := tlv320aic26.o
|
||||||
snd-soc-tlv320aic3x-objs := tlv320aic3x.o
|
snd-soc-tlv320aic3x-objs := tlv320aic3x.o
|
||||||
snd-soc-tlv320aic32x4-objs := tlv320aic32x4.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_STAC9766) += snd-soc-stac9766.o
|
||||||
obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
|
obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
|
||||||
obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
|
obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
|
||||||
|
obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
|
||||||
|
obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
|
||||||
obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
|
obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
|
||||||
obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
|
obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
|
||||||
obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.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"
|
"2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_dac_voice_hpf_corner =
|
static SOC_ENUM_SINGLE_DECL(da7213_dac_voice_hpf_corner,
|
||||||
SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT,
|
DA7213_DAC_FILTERS1,
|
||||||
DA7213_VOICE_HPF_CORNER_MAX,
|
DA7213_VOICE_HPF_CORNER_SHIFT,
|
||||||
da7213_voice_hpf_corner_txt);
|
da7213_voice_hpf_corner_txt);
|
||||||
|
|
||||||
static const struct soc_enum da7213_adc_voice_hpf_corner =
|
static SOC_ENUM_SINGLE_DECL(da7213_adc_voice_hpf_corner,
|
||||||
SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_VOICE_HPF_CORNER_SHIFT,
|
DA7213_ADC_FILTERS1,
|
||||||
DA7213_VOICE_HPF_CORNER_MAX,
|
DA7213_VOICE_HPF_CORNER_SHIFT,
|
||||||
da7213_voice_hpf_corner_txt);
|
da7213_voice_hpf_corner_txt);
|
||||||
|
|
||||||
/* ADC and DAC high pass filter cutoff value */
|
/* ADC and DAC high pass filter cutoff value */
|
||||||
static const char * const da7213_audio_hpf_corner_txt[] = {
|
static const char * const da7213_audio_hpf_corner_txt[] = {
|
||||||
"Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
|
"Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_dac_audio_hpf_corner =
|
static SOC_ENUM_SINGLE_DECL(da7213_dac_audio_hpf_corner,
|
||||||
SOC_ENUM_SINGLE(DA7213_DAC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT,
|
DA7213_DAC_FILTERS1
|
||||||
DA7213_AUDIO_HPF_CORNER_MAX,
|
, DA7213_AUDIO_HPF_CORNER_SHIFT,
|
||||||
da7213_audio_hpf_corner_txt);
|
da7213_audio_hpf_corner_txt);
|
||||||
|
|
||||||
static const struct soc_enum da7213_adc_audio_hpf_corner =
|
static SOC_ENUM_SINGLE_DECL(da7213_adc_audio_hpf_corner,
|
||||||
SOC_ENUM_SINGLE(DA7213_ADC_FILTERS1, DA7213_AUDIO_HPF_CORNER_SHIFT,
|
DA7213_ADC_FILTERS1,
|
||||||
DA7213_AUDIO_HPF_CORNER_MAX,
|
DA7213_AUDIO_HPF_CORNER_SHIFT,
|
||||||
da7213_audio_hpf_corner_txt);
|
da7213_audio_hpf_corner_txt);
|
||||||
|
|
||||||
/* Gain ramping rate value */
|
/* Gain ramping rate value */
|
||||||
static const char * const da7213_gain_ramp_rate_txt[] = {
|
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"
|
"nominal rate / 32"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_gain_ramp_rate =
|
static SOC_ENUM_SINGLE_DECL(da7213_gain_ramp_rate,
|
||||||
SOC_ENUM_SINGLE(DA7213_GAIN_RAMP_CTRL, DA7213_GAIN_RAMP_RATE_SHIFT,
|
DA7213_GAIN_RAMP_CTRL,
|
||||||
DA7213_GAIN_RAMP_RATE_MAX, da7213_gain_ramp_rate_txt);
|
DA7213_GAIN_RAMP_RATE_SHIFT,
|
||||||
|
da7213_gain_ramp_rate_txt);
|
||||||
|
|
||||||
/* DAC noise gate setup time value */
|
/* DAC noise gate setup time value */
|
||||||
static const char * const da7213_dac_ng_setup_time_txt[] = {
|
static const char * const da7213_dac_ng_setup_time_txt[] = {
|
||||||
"256 samples", "512 samples", "1024 samples", "2048 samples"
|
"256 samples", "512 samples", "1024 samples", "2048 samples"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_dac_ng_setup_time =
|
static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_setup_time,
|
||||||
SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
|
DA7213_DAC_NG_SETUP_TIME,
|
||||||
DA7213_DAC_NG_SETUP_TIME_SHIFT,
|
DA7213_DAC_NG_SETUP_TIME_SHIFT,
|
||||||
DA7213_DAC_NG_SETUP_TIME_MAX,
|
da7213_dac_ng_setup_time_txt);
|
||||||
da7213_dac_ng_setup_time_txt);
|
|
||||||
|
|
||||||
/* DAC noise gate rampup rate value */
|
/* DAC noise gate rampup rate value */
|
||||||
static const char * const da7213_dac_ng_rampup_txt[] = {
|
static const char * const da7213_dac_ng_rampup_txt[] = {
|
||||||
"0.02 ms/dB", "0.16 ms/dB"
|
"0.02 ms/dB", "0.16 ms/dB"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_dac_ng_rampup_rate =
|
static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_rampup_rate,
|
||||||
SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
|
DA7213_DAC_NG_SETUP_TIME,
|
||||||
DA7213_DAC_NG_RAMPUP_RATE_SHIFT,
|
DA7213_DAC_NG_RAMPUP_RATE_SHIFT,
|
||||||
DA7213_DAC_NG_RAMP_RATE_MAX,
|
da7213_dac_ng_rampup_txt);
|
||||||
da7213_dac_ng_rampup_txt);
|
|
||||||
|
|
||||||
/* DAC noise gate rampdown rate value */
|
/* DAC noise gate rampdown rate value */
|
||||||
static const char * const da7213_dac_ng_rampdown_txt[] = {
|
static const char * const da7213_dac_ng_rampdown_txt[] = {
|
||||||
"0.64 ms/dB", "20.48 ms/dB"
|
"0.64 ms/dB", "20.48 ms/dB"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_dac_ng_rampdown_rate =
|
static SOC_ENUM_SINGLE_DECL(da7213_dac_ng_rampdown_rate,
|
||||||
SOC_ENUM_SINGLE(DA7213_DAC_NG_SETUP_TIME,
|
DA7213_DAC_NG_SETUP_TIME,
|
||||||
DA7213_DAC_NG_RAMPDN_RATE_SHIFT,
|
DA7213_DAC_NG_RAMPDN_RATE_SHIFT,
|
||||||
DA7213_DAC_NG_RAMP_RATE_MAX,
|
da7213_dac_ng_rampdown_txt);
|
||||||
da7213_dac_ng_rampdown_txt);
|
|
||||||
|
|
||||||
/* DAC soft mute rate value */
|
/* DAC soft mute rate value */
|
||||||
static const char * const da7213_dac_soft_mute_rate_txt[] = {
|
static const char * const da7213_dac_soft_mute_rate_txt[] = {
|
||||||
"1", "2", "4", "8", "16", "32", "64"
|
"1", "2", "4", "8", "16", "32", "64"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_dac_soft_mute_rate =
|
static SOC_ENUM_SINGLE_DECL(da7213_dac_soft_mute_rate,
|
||||||
SOC_ENUM_SINGLE(DA7213_DAC_FILTERS5, DA7213_DAC_SOFTMUTE_RATE_SHIFT,
|
DA7213_DAC_FILTERS5,
|
||||||
DA7213_DAC_SOFTMUTE_RATE_MAX,
|
DA7213_DAC_SOFTMUTE_RATE_SHIFT,
|
||||||
da7213_dac_soft_mute_rate_txt);
|
da7213_dac_soft_mute_rate_txt);
|
||||||
|
|
||||||
/* ALC Attack Rate select */
|
/* ALC Attack Rate select */
|
||||||
static const char * const da7213_alc_attack_rate_txt[] = {
|
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"
|
"5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_alc_attack_rate =
|
static SOC_ENUM_SINGLE_DECL(da7213_alc_attack_rate,
|
||||||
SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_ATTACK_SHIFT,
|
DA7213_ALC_CTRL2,
|
||||||
DA7213_ALC_ATTACK_MAX, da7213_alc_attack_rate_txt);
|
DA7213_ALC_ATTACK_SHIFT,
|
||||||
|
da7213_alc_attack_rate_txt);
|
||||||
|
|
||||||
/* ALC Release Rate select */
|
/* ALC Release Rate select */
|
||||||
static const char * const da7213_alc_release_rate_txt[] = {
|
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"
|
"11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_alc_release_rate =
|
static SOC_ENUM_SINGLE_DECL(da7213_alc_release_rate,
|
||||||
SOC_ENUM_SINGLE(DA7213_ALC_CTRL2, DA7213_ALC_RELEASE_SHIFT,
|
DA7213_ALC_CTRL2,
|
||||||
DA7213_ALC_RELEASE_MAX, da7213_alc_release_rate_txt);
|
DA7213_ALC_RELEASE_SHIFT,
|
||||||
|
da7213_alc_release_rate_txt);
|
||||||
|
|
||||||
/* ALC Hold Time select */
|
/* ALC Hold Time select */
|
||||||
static const char * const da7213_alc_hold_time_txt[] = {
|
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"
|
"253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_alc_hold_time =
|
static SOC_ENUM_SINGLE_DECL(da7213_alc_hold_time,
|
||||||
SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_HOLD_SHIFT,
|
DA7213_ALC_CTRL3,
|
||||||
DA7213_ALC_HOLD_MAX, da7213_alc_hold_time_txt);
|
DA7213_ALC_HOLD_SHIFT,
|
||||||
|
da7213_alc_hold_time_txt);
|
||||||
|
|
||||||
/* ALC Input Signal Tracking rate select */
|
/* ALC Input Signal Tracking rate select */
|
||||||
static const char * const da7213_alc_integ_rate_txt[] = {
|
static const char * const da7213_alc_integ_rate_txt[] = {
|
||||||
"1/4", "1/16", "1/256", "1/65536"
|
"1/4", "1/16", "1/256", "1/65536"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_alc_integ_attack_rate =
|
static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_attack_rate,
|
||||||
SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_ATTACK_SHIFT,
|
DA7213_ALC_CTRL3,
|
||||||
DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt);
|
DA7213_ALC_INTEG_ATTACK_SHIFT,
|
||||||
|
da7213_alc_integ_rate_txt);
|
||||||
|
|
||||||
static const struct soc_enum da7213_alc_integ_release_rate =
|
static SOC_ENUM_SINGLE_DECL(da7213_alc_integ_release_rate,
|
||||||
SOC_ENUM_SINGLE(DA7213_ALC_CTRL3, DA7213_ALC_INTEG_RELEASE_SHIFT,
|
DA7213_ALC_CTRL3,
|
||||||
DA7213_ALC_INTEG_MAX, da7213_alc_integ_rate_txt);
|
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"
|
"Differential", "MIC_P", "MIC_N"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_mic_1_amp_in_sel =
|
static SOC_ENUM_SINGLE_DECL(da7213_mic_1_amp_in_sel,
|
||||||
SOC_ENUM_SINGLE(DA7213_MIC_1_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT,
|
DA7213_MIC_1_CTRL,
|
||||||
DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt);
|
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 =
|
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);
|
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 =
|
static SOC_ENUM_SINGLE_DECL(da7213_mic_2_amp_in_sel,
|
||||||
SOC_ENUM_SINGLE(DA7213_MIC_2_CTRL, DA7213_MIC_AMP_IN_SEL_SHIFT,
|
DA7213_MIC_2_CTRL,
|
||||||
DA7213_MIC_AMP_IN_SEL_MAX, da7213_mic_amp_in_sel_txt);
|
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 =
|
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);
|
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"
|
"ADC Left", "ADC Right", "DAI Input Left", "DAI Input Right"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_dai_l_src =
|
static SOC_ENUM_SINGLE_DECL(da7213_dai_l_src,
|
||||||
SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_L_SRC_SHIFT,
|
DA7213_DIG_ROUTING_DAI,
|
||||||
DA7213_DAI_SRC_MAX, da7213_dai_src_txt);
|
DA7213_DAI_L_SRC_SHIFT,
|
||||||
|
da7213_dai_src_txt);
|
||||||
static const struct snd_kcontrol_new da7213_dai_l_src_mux =
|
static const struct snd_kcontrol_new da7213_dai_l_src_mux =
|
||||||
SOC_DAPM_ENUM("DAI Left Source MUX", da7213_dai_l_src);
|
SOC_DAPM_ENUM("DAI Left Source MUX", da7213_dai_l_src);
|
||||||
|
|
||||||
static const struct soc_enum da7213_dai_r_src =
|
static SOC_ENUM_SINGLE_DECL(da7213_dai_r_src,
|
||||||
SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAI, DA7213_DAI_R_SRC_SHIFT,
|
DA7213_DIG_ROUTING_DAI,
|
||||||
DA7213_DAI_SRC_MAX, da7213_dai_src_txt);
|
DA7213_DAI_R_SRC_SHIFT,
|
||||||
|
da7213_dai_src_txt);
|
||||||
static const struct snd_kcontrol_new da7213_dai_r_src_mux =
|
static const struct snd_kcontrol_new da7213_dai_r_src_mux =
|
||||||
SOC_DAPM_ENUM("DAI Right Source MUX", da7213_dai_r_src);
|
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"
|
"DAI Input Right"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da7213_dac_l_src =
|
static SOC_ENUM_SINGLE_DECL(da7213_dac_l_src,
|
||||||
SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_L_SRC_SHIFT,
|
DA7213_DIG_ROUTING_DAC,
|
||||||
DA7213_DAC_SRC_MAX, da7213_dac_src_txt);
|
DA7213_DAC_L_SRC_SHIFT,
|
||||||
|
da7213_dac_src_txt);
|
||||||
static const struct snd_kcontrol_new da7213_dac_l_src_mux =
|
static const struct snd_kcontrol_new da7213_dac_l_src_mux =
|
||||||
SOC_DAPM_ENUM("DAC Left Source MUX", da7213_dac_l_src);
|
SOC_DAPM_ENUM("DAC Left Source MUX", da7213_dac_l_src);
|
||||||
|
|
||||||
static const struct soc_enum da7213_dac_r_src =
|
static SOC_ENUM_SINGLE_DECL(da7213_dac_r_src,
|
||||||
SOC_ENUM_SINGLE(DA7213_DIG_ROUTING_DAC, DA7213_DAC_R_SRC_SHIFT,
|
DA7213_DIG_ROUTING_DAC,
|
||||||
DA7213_DAC_SRC_MAX, da7213_dac_src_txt);
|
DA7213_DAC_R_SRC_SHIFT,
|
||||||
|
da7213_dac_src_txt);
|
||||||
static const struct snd_kcontrol_new da7213_dac_r_src_mux =
|
static const struct snd_kcontrol_new da7213_dac_r_src_mux =
|
||||||
SOC_DAPM_ENUM("DAC Right Source MUX", da7213_dac_r_src);
|
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"
|
"150Hz", "200Hz", "300Hz", "400Hz"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da732x_dac1_hpf_mode_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_dac1_hpf_mode_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT,
|
DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT,
|
||||||
DA732X_HPF_MODE_MAX, da732x_hpf_mode)
|
da732x_hpf_mode);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_dac2_hpf_mode_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_dac2_hpf_mode_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT,
|
DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT,
|
||||||
DA732X_HPF_MODE_MAX, da732x_hpf_mode)
|
da732x_hpf_mode);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_dac3_hpf_mode_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_dac3_hpf_mode_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT,
|
DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT,
|
||||||
DA732X_HPF_MODE_MAX, da732x_hpf_mode)
|
da732x_hpf_mode);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_adc1_hpf_mode_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_adc1_hpf_mode_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT,
|
DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT,
|
||||||
DA732X_HPF_MODE_MAX, da732x_hpf_mode)
|
da732x_hpf_mode);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_adc2_hpf_mode_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_adc2_hpf_mode_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT,
|
DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT,
|
||||||
DA732X_HPF_MODE_MAX, da732x_hpf_mode)
|
da732x_hpf_mode);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_dac1_hp_filter_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_dac1_hp_filter_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT,
|
DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||||
DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
|
da732x_hpf_music);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_dac2_hp_filter_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_dac2_hp_filter_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT,
|
DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||||
DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
|
da732x_hpf_music);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_dac3_hp_filter_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_dac3_hp_filter_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT,
|
DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||||
DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
|
da732x_hpf_music);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_adc1_hp_filter_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_adc1_hp_filter_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT,
|
DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||||
DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
|
da732x_hpf_music);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_adc2_hp_filter_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_adc2_hp_filter_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT,
|
DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT,
|
||||||
DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
|
da732x_hpf_music);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_dac1_voice_filter_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_dac1_voice_filter_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT,
|
DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||||
DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
|
da732x_hpf_voice);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_dac2_voice_filter_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_dac2_voice_filter_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT,
|
DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||||
DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
|
da732x_hpf_voice);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_dac3_voice_filter_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_dac3_voice_filter_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT,
|
DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||||
DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
|
da732x_hpf_voice);
|
||||||
};
|
|
||||||
|
|
||||||
static const struct soc_enum da732x_adc1_voice_filter_enum[] = {
|
static SOC_ENUM_SINGLE_DECL(da732x_adc1_voice_filter_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT,
|
DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||||
DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
|
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_adc2_voice_filter_enum,
|
||||||
|
DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT,
|
||||||
|
da732x_hpf_voice);
|
||||||
|
|
||||||
static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
|
static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_value *ucontrol)
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
|
@ -714,65 +698,65 @@ static const char *enable_text[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ADC1LMUX */
|
/* ADC1LMUX */
|
||||||
static const struct soc_enum adc1l_enum =
|
static SOC_ENUM_SINGLE_DECL(adc1l_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT,
|
DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT,
|
||||||
DA732X_ADCL_MUX_MAX, adcl_text);
|
adcl_text);
|
||||||
static const struct snd_kcontrol_new adc1l_mux =
|
static const struct snd_kcontrol_new adc1l_mux =
|
||||||
SOC_DAPM_ENUM("ADC Route", adc1l_enum);
|
SOC_DAPM_ENUM("ADC Route", adc1l_enum);
|
||||||
|
|
||||||
/* ADC1RMUX */
|
/* ADC1RMUX */
|
||||||
static const struct soc_enum adc1r_enum =
|
static SOC_ENUM_SINGLE_DECL(adc1r_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT,
|
DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT,
|
||||||
DA732X_ADCR_MUX_MAX, adcr_text);
|
adcr_text);
|
||||||
static const struct snd_kcontrol_new adc1r_mux =
|
static const struct snd_kcontrol_new adc1r_mux =
|
||||||
SOC_DAPM_ENUM("ADC Route", adc1r_enum);
|
SOC_DAPM_ENUM("ADC Route", adc1r_enum);
|
||||||
|
|
||||||
/* ADC2LMUX */
|
/* ADC2LMUX */
|
||||||
static const struct soc_enum adc2l_enum =
|
static SOC_ENUM_SINGLE_DECL(adc2l_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT,
|
DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT,
|
||||||
DA732X_ADCL_MUX_MAX, adcl_text);
|
adcl_text);
|
||||||
static const struct snd_kcontrol_new adc2l_mux =
|
static const struct snd_kcontrol_new adc2l_mux =
|
||||||
SOC_DAPM_ENUM("ADC Route", adc2l_enum);
|
SOC_DAPM_ENUM("ADC Route", adc2l_enum);
|
||||||
|
|
||||||
/* ADC2RMUX */
|
/* ADC2RMUX */
|
||||||
static const struct soc_enum adc2r_enum =
|
static SOC_ENUM_SINGLE_DECL(adc2r_enum,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT,
|
DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT,
|
||||||
DA732X_ADCR_MUX_MAX, adcr_text);
|
adcr_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new adc2r_mux =
|
static const struct snd_kcontrol_new adc2r_mux =
|
||||||
SOC_DAPM_ENUM("ADC Route", adc2r_enum);
|
SOC_DAPM_ENUM("ADC Route", adc2r_enum);
|
||||||
|
|
||||||
static const struct soc_enum da732x_hp_left_output =
|
static SOC_ENUM_SINGLE_DECL(da732x_hp_left_output,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT,
|
DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT,
|
||||||
DA732X_DAC_EN_MAX, enable_text);
|
enable_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new hpl_mux =
|
static const struct snd_kcontrol_new hpl_mux =
|
||||||
SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output);
|
SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output);
|
||||||
|
|
||||||
static const struct soc_enum da732x_hp_right_output =
|
static SOC_ENUM_SINGLE_DECL(da732x_hp_right_output,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT,
|
DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT,
|
||||||
DA732X_DAC_EN_MAX, enable_text);
|
enable_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new hpr_mux =
|
static const struct snd_kcontrol_new hpr_mux =
|
||||||
SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output);
|
SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output);
|
||||||
|
|
||||||
static const struct soc_enum da732x_speaker_output =
|
static SOC_ENUM_SINGLE_DECL(da732x_speaker_output,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT,
|
DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT,
|
||||||
DA732X_DAC_EN_MAX, enable_text);
|
enable_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new spk_mux =
|
static const struct snd_kcontrol_new spk_mux =
|
||||||
SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output);
|
SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output);
|
||||||
|
|
||||||
static const struct soc_enum da732x_lout4_output =
|
static SOC_ENUM_SINGLE_DECL(da732x_lout4_output,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT,
|
DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT,
|
||||||
DA732X_DAC_EN_MAX, enable_text);
|
enable_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new lout4_mux =
|
static const struct snd_kcontrol_new lout4_mux =
|
||||||
SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output);
|
SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output);
|
||||||
|
|
||||||
static const struct soc_enum da732x_lout2_output =
|
static SOC_ENUM_SINGLE_DECL(da732x_lout2_output,
|
||||||
SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT,
|
DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT,
|
||||||
DA732X_DAC_EN_MAX, enable_text);
|
enable_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new lout2_mux =
|
static const struct snd_kcontrol_new lout2_mux =
|
||||||
SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output);
|
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);
|
da732x_hp_dc_offset_cancellation(codec);
|
||||||
|
|
||||||
regcache_cache_only(codec->control_data, false);
|
regcache_cache_only(da732x->regmap, false);
|
||||||
regcache_sync(codec->control_data);
|
regcache_sync(da732x->regmap);
|
||||||
} else {
|
} else {
|
||||||
snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
|
snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
|
||||||
DA732X_BIAS_BOOST_MASK,
|
DA732X_BIAS_BOOST_MASK,
|
||||||
|
|
@ -1511,7 +1495,7 @@ static int da732x_set_bias_level(struct snd_soc_codec *codec,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SND_SOC_BIAS_OFF:
|
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);
|
da732x_set_charge_pump(codec, DA732X_DISABLE_CP);
|
||||||
snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
|
snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
|
||||||
DA732X_BIAS_DIS);
|
DA732X_BIAS_DIS);
|
||||||
|
|
@ -1566,7 +1550,6 @@ static struct snd_soc_codec_driver soc_codec_dev_da732x = {
|
||||||
.dapm_routes = da732x_dapm_routes,
|
.dapm_routes = da732x_dapm_routes,
|
||||||
.num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes),
|
.num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes),
|
||||||
.set_pll = da732x_set_dai_pll,
|
.set_pll = da732x_set_dai_pll,
|
||||||
.reg_cache_size = ARRAY_SIZE(da732x_reg_cache),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int da732x_i2c_probe(struct i2c_client *i2c,
|
static int da732x_i2c_probe(struct i2c_client *i2c,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
|
|
@ -321,22 +323,22 @@ static const char * const da9055_hpf_cutoff_txt[] = {
|
||||||
"Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
|
"Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_dac_hpf_cutoff =
|
static SOC_ENUM_SINGLE_DECL(da9055_dac_hpf_cutoff,
|
||||||
SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt);
|
DA9055_DAC_FILTERS1, 4, da9055_hpf_cutoff_txt);
|
||||||
|
|
||||||
static const struct soc_enum da9055_adc_hpf_cutoff =
|
static SOC_ENUM_SINGLE_DECL(da9055_adc_hpf_cutoff,
|
||||||
SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt);
|
DA9055_ADC_FILTERS1, 4, da9055_hpf_cutoff_txt);
|
||||||
|
|
||||||
/* ADC and DAC voice mode (8kHz) high pass cutoff value */
|
/* ADC and DAC voice mode (8kHz) high pass cutoff value */
|
||||||
static const char * const da9055_vf_cutoff_txt[] = {
|
static const char * const da9055_vf_cutoff_txt[] = {
|
||||||
"2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
|
"2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_dac_vf_cutoff =
|
static SOC_ENUM_SINGLE_DECL(da9055_dac_vf_cutoff,
|
||||||
SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 0, 8, da9055_vf_cutoff_txt);
|
DA9055_DAC_FILTERS1, 0, da9055_vf_cutoff_txt);
|
||||||
|
|
||||||
static const struct soc_enum da9055_adc_vf_cutoff =
|
static SOC_ENUM_SINGLE_DECL(da9055_adc_vf_cutoff,
|
||||||
SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 0, 8, da9055_vf_cutoff_txt);
|
DA9055_ADC_FILTERS1, 0, da9055_vf_cutoff_txt);
|
||||||
|
|
||||||
/* Gain ramping rate value */
|
/* Gain ramping rate value */
|
||||||
static const char * const da9055_gain_ramping_txt[] = {
|
static const char * const da9055_gain_ramping_txt[] = {
|
||||||
|
|
@ -344,44 +346,44 @@ static const char * const da9055_gain_ramping_txt[] = {
|
||||||
"nominal rate / 8"
|
"nominal rate / 8"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_gain_ramping_rate =
|
static SOC_ENUM_SINGLE_DECL(da9055_gain_ramping_rate,
|
||||||
SOC_ENUM_SINGLE(DA9055_GAIN_RAMP_CTRL, 0, 4, da9055_gain_ramping_txt);
|
DA9055_GAIN_RAMP_CTRL, 0, da9055_gain_ramping_txt);
|
||||||
|
|
||||||
/* DAC noise gate setup time value */
|
/* DAC noise gate setup time value */
|
||||||
static const char * const da9055_dac_ng_setup_time_txt[] = {
|
static const char * const da9055_dac_ng_setup_time_txt[] = {
|
||||||
"256 samples", "512 samples", "1024 samples", "2048 samples"
|
"256 samples", "512 samples", "1024 samples", "2048 samples"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_dac_ng_setup_time =
|
static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_setup_time,
|
||||||
SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 0, 4,
|
DA9055_DAC_NG_SETUP_TIME, 0,
|
||||||
da9055_dac_ng_setup_time_txt);
|
da9055_dac_ng_setup_time_txt);
|
||||||
|
|
||||||
/* DAC noise gate rampup rate value */
|
/* DAC noise gate rampup rate value */
|
||||||
static const char * const da9055_dac_ng_rampup_txt[] = {
|
static const char * const da9055_dac_ng_rampup_txt[] = {
|
||||||
"0.02 ms/dB", "0.16 ms/dB"
|
"0.02 ms/dB", "0.16 ms/dB"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_dac_ng_rampup_rate =
|
static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_rampup_rate,
|
||||||
SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 2, 2,
|
DA9055_DAC_NG_SETUP_TIME, 2,
|
||||||
da9055_dac_ng_rampup_txt);
|
da9055_dac_ng_rampup_txt);
|
||||||
|
|
||||||
/* DAC noise gate rampdown rate value */
|
/* DAC noise gate rampdown rate value */
|
||||||
static const char * const da9055_dac_ng_rampdown_txt[] = {
|
static const char * const da9055_dac_ng_rampdown_txt[] = {
|
||||||
"0.64 ms/dB", "20.48 ms/dB"
|
"0.64 ms/dB", "20.48 ms/dB"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_dac_ng_rampdown_rate =
|
static SOC_ENUM_SINGLE_DECL(da9055_dac_ng_rampdown_rate,
|
||||||
SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 3, 2,
|
DA9055_DAC_NG_SETUP_TIME, 3,
|
||||||
da9055_dac_ng_rampdown_txt);
|
da9055_dac_ng_rampdown_txt);
|
||||||
|
|
||||||
/* DAC soft mute rate value */
|
/* DAC soft mute rate value */
|
||||||
static const char * const da9055_dac_soft_mute_rate_txt[] = {
|
static const char * const da9055_dac_soft_mute_rate_txt[] = {
|
||||||
"1", "2", "4", "8", "16", "32", "64"
|
"1", "2", "4", "8", "16", "32", "64"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_dac_soft_mute_rate =
|
static SOC_ENUM_SINGLE_DECL(da9055_dac_soft_mute_rate,
|
||||||
SOC_ENUM_SINGLE(DA9055_DAC_FILTERS5, 4, 7,
|
DA9055_DAC_FILTERS5, 4,
|
||||||
da9055_dac_soft_mute_rate_txt);
|
da9055_dac_soft_mute_rate_txt);
|
||||||
|
|
||||||
/* DAC routing select */
|
/* DAC routing select */
|
||||||
static const char * const da9055_dac_src_txt[] = {
|
static const char * const da9055_dac_src_txt[] = {
|
||||||
|
|
@ -389,40 +391,40 @@ static const char * const da9055_dac_src_txt[] = {
|
||||||
"AIF input right"
|
"AIF input right"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_dac_l_src =
|
static SOC_ENUM_SINGLE_DECL(da9055_dac_l_src,
|
||||||
SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 0, 4, da9055_dac_src_txt);
|
DA9055_DIG_ROUTING_DAC, 0, da9055_dac_src_txt);
|
||||||
|
|
||||||
static const struct soc_enum da9055_dac_r_src =
|
static SOC_ENUM_SINGLE_DECL(da9055_dac_r_src,
|
||||||
SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 4, 4, da9055_dac_src_txt);
|
DA9055_DIG_ROUTING_DAC, 4, da9055_dac_src_txt);
|
||||||
|
|
||||||
/* MIC PGA Left source select */
|
/* MIC PGA Left source select */
|
||||||
static const char * const da9055_mic_l_src_txt[] = {
|
static const char * const da9055_mic_l_src_txt[] = {
|
||||||
"MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L"
|
"MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_mic_l_src =
|
static SOC_ENUM_SINGLE_DECL(da9055_mic_l_src,
|
||||||
SOC_ENUM_SINGLE(DA9055_MIXIN_L_SELECT, 4, 4, da9055_mic_l_src_txt);
|
DA9055_MIXIN_L_SELECT, 4, da9055_mic_l_src_txt);
|
||||||
|
|
||||||
/* MIC PGA Right source select */
|
/* MIC PGA Right source select */
|
||||||
static const char * const da9055_mic_r_src_txt[] = {
|
static const char * const da9055_mic_r_src_txt[] = {
|
||||||
"MIC2_R_L", "MIC2_R", "MIC2_L"
|
"MIC2_R_L", "MIC2_R", "MIC2_L"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_mic_r_src =
|
static SOC_ENUM_SINGLE_DECL(da9055_mic_r_src,
|
||||||
SOC_ENUM_SINGLE(DA9055_MIXIN_R_SELECT, 4, 3, da9055_mic_r_src_txt);
|
DA9055_MIXIN_R_SELECT, 4, da9055_mic_r_src_txt);
|
||||||
|
|
||||||
/* ALC Input Signal Tracking rate select */
|
/* ALC Input Signal Tracking rate select */
|
||||||
static const char * const da9055_signal_tracking_rate_txt[] = {
|
static const char * const da9055_signal_tracking_rate_txt[] = {
|
||||||
"1/4", "1/16", "1/256", "1/65536"
|
"1/4", "1/16", "1/256", "1/65536"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_integ_attack_rate =
|
static SOC_ENUM_SINGLE_DECL(da9055_integ_attack_rate,
|
||||||
SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 4, 4,
|
DA9055_ALC_CTRL3, 4,
|
||||||
da9055_signal_tracking_rate_txt);
|
da9055_signal_tracking_rate_txt);
|
||||||
|
|
||||||
static const struct soc_enum da9055_integ_release_rate =
|
static SOC_ENUM_SINGLE_DECL(da9055_integ_release_rate,
|
||||||
SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 6, 4,
|
DA9055_ALC_CTRL3, 6,
|
||||||
da9055_signal_tracking_rate_txt);
|
da9055_signal_tracking_rate_txt);
|
||||||
|
|
||||||
/* ALC Attack Rate select */
|
/* ALC Attack Rate select */
|
||||||
static const char * const da9055_attack_rate_txt[] = {
|
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"
|
"5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_attack_rate =
|
static SOC_ENUM_SINGLE_DECL(da9055_attack_rate,
|
||||||
SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 0, 13, da9055_attack_rate_txt);
|
DA9055_ALC_CTRL2, 0, da9055_attack_rate_txt);
|
||||||
|
|
||||||
/* ALC Release Rate select */
|
/* ALC Release Rate select */
|
||||||
static const char * const da9055_release_rate_txt[] = {
|
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"
|
"11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_release_rate =
|
static SOC_ENUM_SINGLE_DECL(da9055_release_rate,
|
||||||
SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 4, 11, da9055_release_rate_txt);
|
DA9055_ALC_CTRL2, 4, da9055_release_rate_txt);
|
||||||
|
|
||||||
/* ALC Hold Time select */
|
/* ALC Hold Time select */
|
||||||
static const char * const da9055_hold_time_txt[] = {
|
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"
|
"253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum da9055_hold_time =
|
static SOC_ENUM_SINGLE_DECL(da9055_hold_time,
|
||||||
SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 0, 16, da9055_hold_time_txt);
|
DA9055_ALC_CTRL3, 0, da9055_hold_time_txt);
|
||||||
|
|
||||||
static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
|
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);
|
MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
|
||||||
|
|
||||||
|
static const struct of_device_id da9055_of_match[] = {
|
||||||
|
{ .compatible = "dlg,da9055-codec", },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
/* I2C codec control layer */
|
/* I2C codec control layer */
|
||||||
static struct i2c_driver da9055_i2c_driver = {
|
static struct i2c_driver da9055_i2c_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "da9055-codec",
|
.name = "da9055-codec",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = of_match_ptr(da9055_of_match),
|
||||||
},
|
},
|
||||||
.probe = da9055_i2c_probe,
|
.probe = da9055_i2c_probe,
|
||||||
.remove = da9055_remove,
|
.remove = da9055_remove,
|
||||||
|
|
|
||||||
59
sound/soc/codecs/tlv320aic23-i2c.c
Normal file
59
sound/soc/codecs/tlv320aic23-i2c.c
Normal file
|
|
@ -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");
|
||||||
57
sound/soc/codecs/tlv320aic23-spi.c
Normal file
57
sound/soc/codecs/tlv320aic23-spi.c
Normal file
|
|
@ -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/init.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/i2c.h>
|
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
|
|
@ -51,7 +50,7 @@ static const struct reg_default tlv320aic23_reg[] = {
|
||||||
{ 9, 0x0000 },
|
{ 9, 0x0000 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct regmap_config tlv320aic23_regmap = {
|
const struct regmap_config tlv320aic23_regmap = {
|
||||||
.reg_bits = 7,
|
.reg_bits = 7,
|
||||||
.val_bits = 9,
|
.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 *rec_src_text[] = { "Line", "Mic" };
|
||||||
static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
|
static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
|
||||||
|
|
||||||
static const struct soc_enum rec_src_enum =
|
static SOC_ENUM_SINGLE_DECL(rec_src_enum,
|
||||||
SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
|
TLV320AIC23_ANLG, 2, rec_src_text);
|
||||||
|
|
||||||
static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
|
static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
|
||||||
SOC_DAPM_ENUM("Input Select", rec_src_enum);
|
SOC_DAPM_ENUM("Input Select", rec_src_enum);
|
||||||
|
|
||||||
static const struct soc_enum tlv320aic23_rec_src =
|
static SOC_ENUM_SINGLE_DECL(tlv320aic23_rec_src,
|
||||||
SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
|
TLV320AIC23_ANLG, 2, rec_src_text);
|
||||||
static const struct soc_enum tlv320aic23_deemph =
|
static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph,
|
||||||
SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text);
|
TLV320AIC23_DIGT, 1, deemph_text);
|
||||||
|
|
||||||
static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
|
static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
|
||||||
static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tlv320aic23_probe(struct snd_soc_codec *codec)
|
static int tlv320aic23_codec_probe(struct snd_soc_codec *codec)
|
||||||
{
|
{
|
||||||
int ret;
|
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 = {
|
static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
|
||||||
.probe = tlv320aic23_probe,
|
.probe = tlv320aic23_codec_probe,
|
||||||
.remove = tlv320aic23_remove,
|
.remove = tlv320aic23_remove,
|
||||||
.suspend = tlv320aic23_suspend,
|
.suspend = tlv320aic23_suspend,
|
||||||
.resume = tlv320aic23_resume,
|
.resume = tlv320aic23_resume,
|
||||||
|
|
@ -617,56 +616,24 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
|
||||||
.num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
|
.num_dapm_routes = ARRAY_SIZE(tlv320aic23_intercon),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
int tlv320aic23_probe(struct device *dev, struct regmap *regmap)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
struct aic23 *aic23;
|
struct aic23 *aic23;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
if (IS_ERR(regmap))
|
||||||
return -EINVAL;
|
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)
|
if (aic23 == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
aic23->regmap = devm_regmap_init_i2c(i2c, &tlv320aic23_regmap);
|
aic23->regmap = regmap;
|
||||||
if (IS_ERR(aic23->regmap))
|
|
||||||
return PTR_ERR(aic23->regmap);
|
|
||||||
|
|
||||||
i2c_set_clientdata(i2c, aic23);
|
dev_set_drvdata(dev, aic23);
|
||||||
|
|
||||||
ret = snd_soc_register_codec(&i2c->dev,
|
return snd_soc_register_codec(dev, &soc_codec_dev_tlv320aic23,
|
||||||
&soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1);
|
&tlv320aic23_dai, 1);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
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_DESCRIPTION("ASoC TLV320AIC23 codec driver");
|
||||||
MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
|
MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,12 @@
|
||||||
#ifndef _TLV320AIC23_H
|
#ifndef _TLV320AIC23_H
|
||||||
#define _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 */
|
/* Codec TLV320AIC23 */
|
||||||
#define TLV320AIC23_LINVOL 0x00
|
#define TLV320AIC23_LINVOL 0x00
|
||||||
#define TLV320AIC23_RINVOL 0x01
|
#define TLV320AIC23_RINVOL 0x01
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#include <linux/platform_data/edma.h>
|
#include <linux/platform_data/edma.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
|
|
@ -30,9 +31,34 @@
|
||||||
#include "davinci-i2s.h"
|
#include "davinci-i2s.h"
|
||||||
|
|
||||||
struct snd_soc_card_drvdata_davinci {
|
struct snd_soc_card_drvdata_davinci {
|
||||||
|
struct clk *mclk;
|
||||||
unsigned sysclk;
|
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,
|
static int evm_hw_params(struct snd_pcm_substream *substream,
|
||||||
struct snd_pcm_hw_params *params)
|
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 = {
|
static struct snd_soc_ops evm_ops = {
|
||||||
|
.startup = evm_startup,
|
||||||
|
.shutdown = evm_shutdown,
|
||||||
.hw_params = evm_hw_params,
|
.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);
|
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_dai_link *dai = (struct snd_soc_dai_link *) match->data;
|
||||||
struct snd_soc_card_drvdata_davinci *drvdata = NULL;
|
struct snd_soc_card_drvdata_davinci *drvdata = NULL;
|
||||||
|
struct clk *mclk;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
evm_soc_card.dai_link = dai;
|
evm_soc_card.dai_link = dai;
|
||||||
|
|
@ -367,13 +396,38 @@ static int davinci_evm_probe(struct platform_device *pdev)
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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);
|
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
|
||||||
if (!drvdata)
|
if (!drvdata)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
drvdata->mclk = mclk;
|
||||||
|
|
||||||
ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk);
|
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);
|
snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
|
||||||
ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
|
ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,16 @@
|
||||||
#include "davinci-pcm.h"
|
#include "davinci-pcm.h"
|
||||||
#include "davinci-mcasp.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_mcasp {
|
||||||
struct davinci_pcm_dma_params dma_params[2];
|
struct davinci_pcm_dma_params dma_params[2];
|
||||||
struct snd_dmaengine_dai_dma_data dma_data[2];
|
struct snd_dmaengine_dai_dma_data dma_data[2];
|
||||||
|
|
@ -53,6 +63,9 @@ struct davinci_mcasp {
|
||||||
u16 bclk_lrclk_ratio;
|
u16 bclk_lrclk_ratio;
|
||||||
int streams;
|
int streams;
|
||||||
|
|
||||||
|
int sysclk_freq;
|
||||||
|
bool bclk_master;
|
||||||
|
|
||||||
/* McASP FIFO related */
|
/* McASP FIFO related */
|
||||||
u8 txnumevt;
|
u8 txnumevt;
|
||||||
u8 rxnumevt;
|
u8 rxnumevt;
|
||||||
|
|
@ -60,15 +73,7 @@ struct davinci_mcasp {
|
||||||
bool dat_port;
|
bool dat_port;
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
struct {
|
struct davinci_mcasp_context context;
|
||||||
u32 txfmtctl;
|
|
||||||
u32 rxfmtctl;
|
|
||||||
u32 txfmt;
|
|
||||||
u32 rxfmt;
|
|
||||||
u32 aclkxctl;
|
|
||||||
u32 aclkrctl;
|
|
||||||
u32 pdir;
|
|
||||||
} context;
|
|
||||||
#endif
|
#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, ACLKX | ACLKR);
|
||||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR);
|
mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR);
|
||||||
|
mcasp->bclk_master = 1;
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_CBM_CFS:
|
case SND_SOC_DAIFMT_CBM_CFS:
|
||||||
/* codec is clock master and frame slave */
|
/* 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_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, ACLKX | ACLKR);
|
||||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR);
|
mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AFSX | AFSR);
|
||||||
|
mcasp->bclk_master = 0;
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_CBM_CFM:
|
case SND_SOC_DAIFMT_CBM_CFM:
|
||||||
/* codec is clock and frame master */
|
/* 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,
|
mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG,
|
||||||
ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR);
|
ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR);
|
||||||
|
mcasp->bclk_master = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
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_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mcasp->sysclk_freq = freq;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -603,20 +613,23 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
|
||||||
u8 fifo_level;
|
u8 fifo_level;
|
||||||
u8 slots = mcasp->tdm_slots;
|
u8 slots = mcasp->tdm_slots;
|
||||||
u8 active_serializers;
|
u8 active_serializers;
|
||||||
int channels;
|
int channels = params_channels(params);
|
||||||
int ret;
|
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)
|
ret = mcasp_common_hw_param(mcasp, substream->stream, channels);
|
||||||
return -EINVAL;
|
if (ret)
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
return ret;
|
||||||
fifo_level = mcasp->txnumevt * active_serializers;
|
|
||||||
else
|
|
||||||
fifo_level = mcasp->rxnumevt * active_serializers;
|
|
||||||
|
|
||||||
if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
|
if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
|
||||||
ret = mcasp_dit_hw_param(mcasp);
|
ret = mcasp_dit_hw_param(mcasp);
|
||||||
|
|
@ -658,6 +671,13 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
|
||||||
return -EINVAL;
|
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)
|
if (mcasp->version == MCASP_VERSION_2 && !fifo_level)
|
||||||
dma_params->acnt = 4;
|
dma_params->acnt = 4;
|
||||||
else
|
else
|
||||||
|
|
@ -719,6 +739,43 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
|
||||||
.set_sysclk = davinci_mcasp_set_sysclk,
|
.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_RATES SNDRV_PCM_RATE_8000_192000
|
||||||
|
|
||||||
#define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \
|
#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[] = {
|
static struct snd_soc_dai_driver davinci_mcasp_dai[] = {
|
||||||
{
|
{
|
||||||
.name = "davinci-mcasp.0",
|
.name = "davinci-mcasp.0",
|
||||||
|
.suspend = davinci_mcasp_suspend,
|
||||||
|
.resume = davinci_mcasp_resume,
|
||||||
.playback = {
|
.playback = {
|
||||||
.channels_min = 2,
|
.channels_min = 2,
|
||||||
.channels_max = 32 * 16,
|
.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. */
|
/* 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,
|
.tx_dma_offset = 0x400,
|
||||||
.rx_dma_offset = 0x400,
|
.rx_dma_offset = 0x400,
|
||||||
.asp_chan_q = EVENTQ_0,
|
.asp_chan_q = EVENTQ_0,
|
||||||
.version = MCASP_VERSION_1,
|
.version = MCASP_VERSION_1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct snd_platform_data da830_mcasp_pdata = {
|
static struct davinci_mcasp_pdata da830_mcasp_pdata = {
|
||||||
.tx_dma_offset = 0x2000,
|
.tx_dma_offset = 0x2000,
|
||||||
.rx_dma_offset = 0x2000,
|
.rx_dma_offset = 0x2000,
|
||||||
.asp_chan_q = EVENTQ_0,
|
.asp_chan_q = EVENTQ_0,
|
||||||
.version = MCASP_VERSION_2,
|
.version = MCASP_VERSION_2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct snd_platform_data am33xx_mcasp_pdata = {
|
static struct davinci_mcasp_pdata am33xx_mcasp_pdata = {
|
||||||
.tx_dma_offset = 0,
|
.tx_dma_offset = 0,
|
||||||
.rx_dma_offset = 0,
|
.rx_dma_offset = 0,
|
||||||
.asp_chan_q = EVENTQ_0,
|
.asp_chan_q = EVENTQ_0,
|
||||||
.version = MCASP_VERSION_3,
|
.version = MCASP_VERSION_3,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct snd_platform_data dra7_mcasp_pdata = {
|
static struct davinci_mcasp_pdata dra7_mcasp_pdata = {
|
||||||
.tx_dma_offset = 0x200,
|
.tx_dma_offset = 0x200,
|
||||||
.rx_dma_offset = 0x284,
|
.rx_dma_offset = 0x284,
|
||||||
.asp_chan_q = EVENTQ_0,
|
.asp_chan_q = EVENTQ_0,
|
||||||
|
|
@ -857,11 +916,11 @@ err1:
|
||||||
return ret;
|
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 platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
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 =
|
const struct of_device_id *match =
|
||||||
of_match_device(mcasp_dt_ids, &pdev->dev);
|
of_match_device(mcasp_dt_ids, &pdev->dev);
|
||||||
struct of_phandle_args dma_spec;
|
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;
|
pdata = pdev->dev.platform_data;
|
||||||
return pdata;
|
return pdata;
|
||||||
} else if (match) {
|
} else if (match) {
|
||||||
pdata = (struct snd_platform_data *) match->data;
|
pdata = (struct davinci_mcasp_pdata*) match->data;
|
||||||
} else {
|
} else {
|
||||||
/* control shouldn't reach here. something is wrong */
|
/* control shouldn't reach here. something is wrong */
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|
@ -966,9 +1025,9 @@ nodata:
|
||||||
|
|
||||||
static int davinci_mcasp_probe(struct platform_device *pdev)
|
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 resource *mem, *ioarea, *res, *dat;
|
||||||
struct snd_platform_data *pdata;
|
struct davinci_mcasp_pdata *pdata;
|
||||||
struct davinci_mcasp *mcasp;
|
struct davinci_mcasp *mcasp;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
@ -1035,41 +1094,41 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
|
||||||
if (dat)
|
if (dat)
|
||||||
mcasp->dat_port = true;
|
mcasp->dat_port = true;
|
||||||
|
|
||||||
dma_data = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
|
dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
|
||||||
dma_data->asp_chan_q = pdata->asp_chan_q;
|
dma_params->asp_chan_q = pdata->asp_chan_q;
|
||||||
dma_data->ram_chan_q = pdata->ram_chan_q;
|
dma_params->ram_chan_q = pdata->ram_chan_q;
|
||||||
dma_data->sram_pool = pdata->sram_pool;
|
dma_params->sram_pool = pdata->sram_pool;
|
||||||
dma_data->sram_size = pdata->sram_size_playback;
|
dma_params->sram_size = pdata->sram_size_playback;
|
||||||
if (dat)
|
if (dat)
|
||||||
dma_data->dma_addr = dat->start;
|
dma_params->dma_addr = dat->start;
|
||||||
else
|
else
|
||||||
dma_data->dma_addr = mem->start + pdata->tx_dma_offset;
|
dma_params->dma_addr = mem->start + pdata->tx_dma_offset;
|
||||||
|
|
||||||
/* Unconditional dmaengine stuff */
|
/* 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);
|
res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
|
||||||
if (res)
|
if (res)
|
||||||
dma_data->channel = res->start;
|
dma_params->channel = res->start;
|
||||||
else
|
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_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE];
|
||||||
dma_data->asp_chan_q = pdata->asp_chan_q;
|
dma_params->asp_chan_q = pdata->asp_chan_q;
|
||||||
dma_data->ram_chan_q = pdata->ram_chan_q;
|
dma_params->ram_chan_q = pdata->ram_chan_q;
|
||||||
dma_data->sram_pool = pdata->sram_pool;
|
dma_params->sram_pool = pdata->sram_pool;
|
||||||
dma_data->sram_size = pdata->sram_size_capture;
|
dma_params->sram_size = pdata->sram_size_capture;
|
||||||
if (dat)
|
if (dat)
|
||||||
dma_data->dma_addr = dat->start;
|
dma_params->dma_addr = dat->start;
|
||||||
else
|
else
|
||||||
dma_data->dma_addr = mem->start + pdata->rx_dma_offset;
|
dma_params->dma_addr = mem->start + pdata->rx_dma_offset;
|
||||||
|
|
||||||
/* Unconditional dmaengine stuff */
|
/* 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) {
|
if (mcasp->version < MCASP_VERSION_3) {
|
||||||
mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE;
|
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;
|
mcasp->dat_port = true;
|
||||||
} else {
|
} else {
|
||||||
mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE;
|
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);
|
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
|
||||||
if (res)
|
if (res)
|
||||||
dma_data->channel = res->start;
|
dma_params->channel = res->start;
|
||||||
else
|
else
|
||||||
dma_data->channel = pdata->rx_dma_channel;
|
dma_params->channel = pdata->rx_dma_channel;
|
||||||
|
|
||||||
/* Unconditional dmaengine stuff */
|
/* Unconditional dmaengine stuff */
|
||||||
mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = "tx";
|
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;
|
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 = {
|
static struct platform_driver davinci_mcasp_driver = {
|
||||||
.probe = davinci_mcasp_probe,
|
.probe = davinci_mcasp_probe,
|
||||||
.remove = davinci_mcasp_remove,
|
.remove = davinci_mcasp_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "davinci-mcasp",
|
.name = "davinci-mcasp",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.pm = &davinci_mcasp_pm_ops,
|
|
||||||
.of_match_table = mcasp_dt_ids,
|
.of_match_table = mcasp_dt_ids,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
config SND_SOC_FSL_SAI
|
config SND_SOC_FSL_SAI
|
||||||
tristate
|
tristate
|
||||||
|
select REGMAP_MMIO
|
||||||
select SND_SOC_GENERIC_DMAENGINE_PCM
|
select SND_SOC_GENERIC_DMAENGINE_PCM
|
||||||
|
|
||||||
config SND_SOC_FSL_SSI
|
config SND_SOC_FSL_SSI
|
||||||
|
|
@ -7,9 +8,11 @@ config SND_SOC_FSL_SSI
|
||||||
|
|
||||||
config SND_SOC_FSL_SPDIF
|
config SND_SOC_FSL_SPDIF
|
||||||
tristate
|
tristate
|
||||||
|
select REGMAP_MMIO
|
||||||
|
|
||||||
config SND_SOC_FSL_ESAI
|
config SND_SOC_FSL_ESAI
|
||||||
tristate
|
tristate
|
||||||
|
select REGMAP_MMIO
|
||||||
|
|
||||||
config SND_SOC_FSL_UTILS
|
config SND_SOC_FSL_UTILS
|
||||||
tristate
|
tristate
|
||||||
|
|
@ -168,12 +171,14 @@ config SND_SOC_EUKREA_TLV320
|
||||||
depends on MACH_EUKREA_MBIMX27_BASEBOARD \
|
depends on MACH_EUKREA_MBIMX27_BASEBOARD \
|
||||||
|| MACH_EUKREA_MBIMXSD25_BASEBOARD \
|
|| MACH_EUKREA_MBIMXSD25_BASEBOARD \
|
||||||
|| MACH_EUKREA_MBIMXSD35_BASEBOARD \
|
|| MACH_EUKREA_MBIMXSD35_BASEBOARD \
|
||||||
|| MACH_EUKREA_MBIMXSD51_BASEBOARD
|
|| MACH_EUKREA_MBIMXSD51_BASEBOARD \
|
||||||
|
|| (OF && ARM)
|
||||||
depends on I2C
|
depends on I2C
|
||||||
select SND_SOC_TLV320AIC23
|
select SND_SOC_TLV320AIC23_I2C
|
||||||
select SND_SOC_IMX_PCM_FIQ
|
|
||||||
select SND_SOC_IMX_AUDMUX
|
select SND_SOC_IMX_AUDMUX
|
||||||
select SND_SOC_IMX_SSI
|
select SND_SOC_IMX_SSI
|
||||||
|
select SND_SOC_FSL_SSI
|
||||||
|
select SND_SOC_IMX_PCM_DMA
|
||||||
help
|
help
|
||||||
Enable I2S based access to the TLV320AIC23B codec attached
|
Enable I2S based access to the TLV320AIC23B codec attached
|
||||||
to the SSI interface
|
to the SSI interface
|
||||||
|
|
@ -204,7 +209,6 @@ config SND_SOC_IMX_SPDIF
|
||||||
tristate "SoC Audio support for i.MX boards with S/PDIF"
|
tristate "SoC Audio support for i.MX boards with S/PDIF"
|
||||||
select SND_SOC_IMX_PCM_DMA
|
select SND_SOC_IMX_PCM_DMA
|
||||||
select SND_SOC_FSL_SPDIF
|
select SND_SOC_FSL_SPDIF
|
||||||
select REGMAP_MMIO
|
|
||||||
help
|
help
|
||||||
SoC Audio support for i.MX boards with S/PDIF
|
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
|
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/module.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_platform.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
|
|
@ -26,6 +29,7 @@
|
||||||
|
|
||||||
#include "../codecs/tlv320aic23.h"
|
#include "../codecs/tlv320aic23.h"
|
||||||
#include "imx-ssi.h"
|
#include "imx-ssi.h"
|
||||||
|
#include "fsl_ssi.h"
|
||||||
#include "imx-audmux.h"
|
#include "imx-audmux.h"
|
||||||
|
|
||||||
#define CODEC_CLOCK 12000000
|
#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 |
|
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
|
||||||
SND_SOC_DAIFMT_NB_NF |
|
SND_SOC_DAIFMT_NB_NF |
|
||||||
SND_SOC_DAIFMT_CBM_CFM);
|
SND_SOC_DAIFMT_CBM_CFM);
|
||||||
if (ret) {
|
/* fsl_ssi lacks the set_fmt ops. */
|
||||||
|
if (ret && ret != -ENOTSUPP) {
|
||||||
dev_err(cpu_dai->dev,
|
dev_err(cpu_dai->dev,
|
||||||
"Failed to set the cpu dai format.\n");
|
"Failed to set the cpu dai format.\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -63,11 +68,13 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
|
||||||
"Failed to set the codec sysclk.\n");
|
"Failed to set the codec sysclk.\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_soc_dai_set_tdm_slot(cpu_dai, 0xffffffc, 0xffffffc, 2, 0);
|
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,
|
ret = snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
|
||||||
SND_SOC_CLOCK_IN);
|
SND_SOC_CLOCK_IN);
|
||||||
if (ret) {
|
/* fsl_ssi lacks the set_sysclk ops */
|
||||||
|
if (ret && ret != -EINVAL) {
|
||||||
dev_err(cpu_dai->dev,
|
dev_err(cpu_dai->dev,
|
||||||
"Can't set the IMX_SSP_SYS_CLK CPU system clock.\n");
|
"Can't set the IMX_SSP_SYS_CLK CPU system clock.\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
|
@ -84,14 +91,10 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = {
|
||||||
.name = "tlv320aic23",
|
.name = "tlv320aic23",
|
||||||
.stream_name = "TLV320AIC23",
|
.stream_name = "TLV320AIC23",
|
||||||
.codec_dai_name = "tlv320aic23-hifi",
|
.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,
|
.ops = &eukrea_tlv320_snd_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct snd_soc_card eukrea_tlv320 = {
|
static struct snd_soc_card eukrea_tlv320 = {
|
||||||
.name = "cpuimx-audio",
|
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.dai_link = &eukrea_tlv320_dai,
|
.dai_link = &eukrea_tlv320_dai,
|
||||||
.num_links = 1,
|
.num_links = 1,
|
||||||
|
|
@ -101,8 +104,65 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int int_port = 0, ext_port;
|
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_configure_port(MX27_AUDMUX_HPCR1_SSI0,
|
||||||
IMX_AUDMUX_V1_PCR_SYN |
|
IMX_AUDMUX_V1_PCR_SYN |
|
||||||
IMX_AUDMUX_V1_PCR_TFSDIR |
|
IMX_AUDMUX_V1_PCR_TFSDIR |
|
||||||
|
|
@ -119,8 +179,12 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
|
||||||
);
|
);
|
||||||
} else if (machine_is_eukrea_cpuimx25sd() ||
|
} else if (machine_is_eukrea_cpuimx25sd() ||
|
||||||
machine_is_eukrea_cpuimx35sd() ||
|
machine_is_eukrea_cpuimx35sd() ||
|
||||||
machine_is_eukrea_cpuimx51sd()) {
|
machine_is_eukrea_cpuimx51sd() ||
|
||||||
ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3;
|
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_configure_port(int_port,
|
||||||
IMX_AUDMUX_V2_PTCR_SYN |
|
IMX_AUDMUX_V2_PTCR_SYN |
|
||||||
IMX_AUDMUX_V2_PTCR_TFSDIR |
|
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)
|
IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
/* return happy. We might run on a totally different machine */
|
if (np) {
|
||||||
return 0;
|
/* 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);
|
ret = snd_soc_register_card(&eukrea_tlv320);
|
||||||
|
err:
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
|
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
|
||||||
|
if (np)
|
||||||
|
of_node_put(ssi_np);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -153,10 +230,17 @@ static int eukrea_tlv320_remove(struct platform_device *pdev)
|
||||||
return 0;
|
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 = {
|
static struct platform_driver eukrea_tlv320_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "eukrea_tlv320",
|
.name = "eukrea_tlv320",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = imx_tlv320_dt_ids,
|
||||||
},
|
},
|
||||||
.probe = eukrea_tlv320_probe,
|
.probe = eukrea_tlv320_probe,
|
||||||
.remove = eukrea_tlv320_remove,
|
.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,
|
static int fsl_esai_startup(struct snd_pcm_substream *substream,
|
||||||
struct snd_soc_dai *dai)
|
struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
|
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
|
* 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
|
* clocks, so keep all clocks open/close at the same time for safety
|
||||||
*/
|
*/
|
||||||
clk_prepare_enable(esai_priv->coreclk);
|
ret = clk_prepare_enable(esai_priv->coreclk);
|
||||||
if (!IS_ERR(esai_priv->extalclk))
|
if (ret)
|
||||||
clk_prepare_enable(esai_priv->extalclk);
|
return ret;
|
||||||
if (!IS_ERR(esai_priv->fsysclk))
|
if (!IS_ERR(esai_priv->extalclk)) {
|
||||||
clk_prepare_enable(esai_priv->fsysclk);
|
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) {
|
if (!dai->active) {
|
||||||
/* Reset Port C */
|
/* Reset Port C */
|
||||||
|
|
@ -463,6 +472,14 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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,
|
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_bits = 32,
|
||||||
.reg_stride = 4,
|
.reg_stride = 4,
|
||||||
.val_bits = 32,
|
.val_bits = 32,
|
||||||
|
|
@ -687,6 +704,9 @@ static int fsl_esai_probe(struct platform_device *pdev)
|
||||||
esai_priv->pdev = pdev;
|
esai_priv->pdev = pdev;
|
||||||
strcpy(esai_priv->name, np->name);
|
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 */
|
/* Get the addresses and IRQ */
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
regs = devm_ioremap_resource(&pdev->dev, res);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/dmaengine.h>
|
#include <linux/dmaengine.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/dmaengine_pcm.h>
|
#include <sound/dmaengine_pcm.h>
|
||||||
|
|
@ -22,34 +23,6 @@
|
||||||
|
|
||||||
#include "fsl_sai.h"
|
#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,
|
static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
|
||||||
int clk_id, unsigned int freq, int fsl_dir)
|
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
|
else
|
||||||
reg_cr2 = FSL_SAI_RCR2;
|
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;
|
val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
|
||||||
|
|
||||||
switch (clk_id) {
|
switch (clk_id) {
|
||||||
|
|
@ -81,7 +55,7 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sai_writel(sai, val_cr2, sai->base + reg_cr2);
|
regmap_write(sai->regmap, reg_cr2, val_cr2);
|
||||||
|
|
||||||
return 0;
|
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,
|
static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
|
||||||
int clk_id, unsigned int freq, int dir)
|
int clk_id, unsigned int freq, int dir)
|
||||||
{
|
{
|
||||||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (dir == SND_SOC_CLOCK_IN)
|
if (dir == SND_SOC_CLOCK_IN)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = clk_prepare_enable(sai->clk);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
|
ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
|
||||||
FSL_FMT_TRANSMITTER);
|
FSL_FMT_TRANSMITTER);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", 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,
|
ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
|
||||||
FSL_FMT_RECEIVER);
|
FSL_FMT_RECEIVER);
|
||||||
if (ret) {
|
if (ret)
|
||||||
dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", 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;
|
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;
|
reg_cr4 = FSL_SAI_RCR4;
|
||||||
}
|
}
|
||||||
|
|
||||||
val_cr2 = sai_readl(sai, sai->base + reg_cr2);
|
regmap_read(sai->regmap, reg_cr2, &val_cr2);
|
||||||
val_cr4 = sai_readl(sai, sai->base + reg_cr4);
|
regmap_read(sai->regmap, reg_cr4, &val_cr4);
|
||||||
|
|
||||||
if (sai->big_endian_data)
|
if (sai->big_endian_data)
|
||||||
val_cr4 &= ~FSL_SAI_CR4_MF;
|
val_cr4 &= ~FSL_SAI_CR4_MF;
|
||||||
else
|
else
|
||||||
val_cr4 |= FSL_SAI_CR4_MF;
|
val_cr4 |= FSL_SAI_CR4_MF;
|
||||||
|
|
||||||
|
/* DAI mode */
|
||||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||||
case SND_SOC_DAIFMT_I2S:
|
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;
|
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:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DAI clock inversion */
|
||||||
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||||
case SND_SOC_DAIFMT_IB_IF:
|
case SND_SOC_DAIFMT_IB_IF:
|
||||||
val_cr4 |= FSL_SAI_CR4_FSP;
|
/* Invert both clocks */
|
||||||
val_cr2 &= ~FSL_SAI_CR2_BCP;
|
val_cr2 ^= FSL_SAI_CR2_BCP;
|
||||||
|
val_cr4 ^= FSL_SAI_CR4_FSP;
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_IB_NF:
|
case SND_SOC_DAIFMT_IB_NF:
|
||||||
val_cr4 &= ~FSL_SAI_CR4_FSP;
|
/* Invert bit clock */
|
||||||
val_cr2 &= ~FSL_SAI_CR2_BCP;
|
val_cr2 ^= FSL_SAI_CR2_BCP;
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_NB_IF:
|
case SND_SOC_DAIFMT_NB_IF:
|
||||||
val_cr4 |= FSL_SAI_CR4_FSP;
|
/* Invert frame clock */
|
||||||
val_cr2 |= FSL_SAI_CR2_BCP;
|
val_cr4 ^= FSL_SAI_CR4_FSP;
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_NB_NF:
|
case SND_SOC_DAIFMT_NB_NF:
|
||||||
val_cr4 &= ~FSL_SAI_CR4_FSP;
|
/* Nothing to do for both normal cases */
|
||||||
val_cr2 |= FSL_SAI_CR2_BCP;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DAI clock master masks */
|
||||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||||
case SND_SOC_DAIFMT_CBS_CFS:
|
case SND_SOC_DAIFMT_CBS_CFS:
|
||||||
val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
|
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_cr2 &= ~FSL_SAI_CR2_BCD_MSTR;
|
||||||
val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR;
|
val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR;
|
||||||
break;
|
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:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sai_writel(sai, val_cr2, sai->base + reg_cr2);
|
regmap_write(sai->regmap, reg_cr2, val_cr2);
|
||||||
sai_writel(sai, val_cr4, sai->base + reg_cr4);
|
regmap_write(sai->regmap, reg_cr4, val_cr4);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
|
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;
|
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);
|
ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", 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);
|
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);
|
dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret);
|
||||||
goto err_clk;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_clk:
|
|
||||||
clk_disable_unprepare(sai->clk);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -235,16 +238,19 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
|
||||||
reg_mr = FSL_SAI_RMR;
|
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_SYWD_MASK;
|
||||||
val_cr4 &= ~FSL_SAI_CR4_FRSZ_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_WNW_MASK;
|
||||||
val_cr5 &= ~FSL_SAI_CR5_W0W_MASK;
|
val_cr5 &= ~FSL_SAI_CR5_W0W_MASK;
|
||||||
val_cr5 &= ~FSL_SAI_CR5_FBT_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_WNW(word_width);
|
||||||
val_cr5 |= FSL_SAI_CR5_W0W(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_cr4 |= FSL_SAI_CR4_FRSZ(channels);
|
||||||
val_mr = ~0UL - ((1 << channels) - 1);
|
val_mr = ~0UL - ((1 << channels) - 1);
|
||||||
|
|
||||||
sai_writel(sai, val_cr4, sai->base + reg_cr4);
|
regmap_write(sai->regmap, reg_cr4, val_cr4);
|
||||||
sai_writel(sai, val_cr5, sai->base + reg_cr5);
|
regmap_write(sai->regmap, reg_cr5, val_cr5);
|
||||||
sai_writel(sai, val_mr, sai->base + reg_mr);
|
regmap_write(sai->regmap, reg_mr, val_mr);
|
||||||
|
|
||||||
return 0;
|
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 snd_soc_dai *cpu_dai)
|
||||||
{
|
{
|
||||||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(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;
|
* The transmitter bit clock and frame sync are to be
|
||||||
sai_writel(sai, val_cr2, sai->base + FSL_SAI_TCR2);
|
* 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);
|
regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr);
|
||||||
val_cr2 |= FSL_SAI_CR2_SYNC;
|
regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr);
|
||||||
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);
|
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
tcsr |= FSL_SAI_CSR_FRDE;
|
tcsr |= FSL_SAI_CSR_FRDE;
|
||||||
rcsr &= ~FSL_SAI_CSR_FRDE;
|
rcsr &= ~FSL_SAI_CSR_FRDE;
|
||||||
reg_cr3 = FSL_SAI_TCR3;
|
|
||||||
} else {
|
} else {
|
||||||
rcsr |= FSL_SAI_CSR_FRDE;
|
rcsr |= FSL_SAI_CSR_FRDE;
|
||||||
tcsr &= ~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) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
case SNDRV_PCM_TRIGGER_RESUME:
|
case SNDRV_PCM_TRIGGER_RESUME:
|
||||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||||
tcsr |= FSL_SAI_CSR_TERE;
|
tcsr |= FSL_SAI_CSR_TERE;
|
||||||
rcsr |= FSL_SAI_CSR_TERE;
|
rcsr |= FSL_SAI_CSR_TERE;
|
||||||
val_cr3 |= FSL_SAI_CR3_TRCE;
|
|
||||||
|
|
||||||
sai_writel(sai, val_cr3, sai->base + reg_cr3);
|
regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr);
|
||||||
sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR);
|
regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr);
|
||||||
sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SNDRV_PCM_TRIGGER_STOP:
|
case SNDRV_PCM_TRIGGER_STOP:
|
||||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
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;
|
rcsr &= ~FSL_SAI_CSR_TERE;
|
||||||
}
|
}
|
||||||
|
|
||||||
val_cr3 &= ~FSL_SAI_CR3_TRCE;
|
regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr);
|
||||||
|
regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -331,16 +332,32 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
|
||||||
struct snd_soc_dai *cpu_dai)
|
struct snd_soc_dai *cpu_dai)
|
||||||
{
|
{
|
||||||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(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,
|
static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
|
||||||
struct snd_soc_dai *cpu_dai)
|
struct snd_soc_dai *cpu_dai)
|
||||||
{
|
{
|
||||||
struct fsl_sai *sai = snd_soc_dai_get_drvdata(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 = {
|
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)
|
static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
|
||||||
{
|
{
|
||||||
struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
|
struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = clk_prepare_enable(sai->clk);
|
regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0);
|
||||||
if (ret)
|
regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0);
|
||||||
return ret;
|
regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
|
||||||
|
FSL_SAI_MAXBURST_TX * 2);
|
||||||
sai_writel(sai, 0x0, sai->base + FSL_SAI_RCSR);
|
regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
|
||||||
sai_writel(sai, 0x0, sai->base + FSL_SAI_TCSR);
|
FSL_SAI_MAXBURST_RX - 1);
|
||||||
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);
|
|
||||||
|
|
||||||
snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
|
snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
|
||||||
&sai->dma_params_rx);
|
&sai->dma_params_rx);
|
||||||
|
|
@ -397,26 +409,109 @@ static const struct snd_soc_component_driver fsl_component = {
|
||||||
.name = "fsl-sai",
|
.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)
|
static int fsl_sai_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
struct fsl_sai *sai;
|
struct fsl_sai *sai;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
void __iomem *base;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
|
sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
|
||||||
if (!sai)
|
if (!sai)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
|
||||||
sai->base = devm_ioremap_resource(&pdev->dev, res);
|
if (sai->big_endian_regs)
|
||||||
if (IS_ERR(sai->base))
|
fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
|
||||||
return PTR_ERR(sai->base);
|
|
||||||
|
|
||||||
sai->clk = devm_clk_get(&pdev->dev, "sai");
|
sai->big_endian_data = of_property_read_bool(np, "big-endian-data");
|
||||||
if (IS_ERR(sai->clk)) {
|
|
||||||
dev_err(&pdev->dev, "Cannot get SAI's clock\n");
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
return PTR_ERR(sai->clk);
|
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;
|
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_rx.maxburst = FSL_SAI_MAXBURST_RX;
|
||||||
sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
|
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);
|
platform_set_drvdata(pdev, sai);
|
||||||
|
|
||||||
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
|
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
|
||||||
|
|
|
||||||
|
|
@ -15,31 +15,36 @@
|
||||||
SNDRV_PCM_FMTBIT_S20_3LE |\
|
SNDRV_PCM_FMTBIT_S20_3LE |\
|
||||||
SNDRV_PCM_FMTBIT_S24_LE)
|
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 */
|
/* 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_TERE BIT(31)
|
||||||
#define FSL_SAI_CSR_FWF BIT(17)
|
#define FSL_SAI_CSR_FWF BIT(17)
|
||||||
#define FSL_SAI_CSR_FRIE BIT(8)
|
#define FSL_SAI_CSR_FRIE BIT(8)
|
||||||
#define FSL_SAI_CSR_FRDE BIT(0)
|
#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 */
|
/* SAI Transmit and Recieve Configuration 1 Register */
|
||||||
#define FSL_SAI_TCR1 0x04
|
#define FSL_SAI_CR1_RFW_MASK 0x1f
|
||||||
#define FSL_SAI_RCR1 0x84
|
|
||||||
|
|
||||||
/* SAI Transmit and Recieve Configuration 2 Register */
|
/* 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_SYNC BIT(30)
|
||||||
#define FSL_SAI_CR2_MSEL_MASK (0xff << 26)
|
#define FSL_SAI_CR2_MSEL_MASK (0xff << 26)
|
||||||
#define FSL_SAI_CR2_MSEL_BUS 0
|
#define FSL_SAI_CR2_MSEL_BUS 0
|
||||||
|
|
@ -50,15 +55,11 @@
|
||||||
#define FSL_SAI_CR2_BCD_MSTR BIT(24)
|
#define FSL_SAI_CR2_BCD_MSTR BIT(24)
|
||||||
|
|
||||||
/* SAI Transmit and Recieve Configuration 3 Register */
|
/* 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_TRCE BIT(16)
|
||||||
#define FSL_SAI_CR3_WDFL(x) (x)
|
#define FSL_SAI_CR3_WDFL(x) (x)
|
||||||
#define FSL_SAI_CR3_WDFL_MASK 0x1f
|
#define FSL_SAI_CR3_WDFL_MASK 0x1f
|
||||||
|
|
||||||
/* SAI Transmit and Recieve Configuration 4 Register */
|
/* 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(x) (((x) - 1) << 16)
|
||||||
#define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16)
|
#define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16)
|
||||||
#define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8)
|
#define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8)
|
||||||
|
|
@ -69,8 +70,6 @@
|
||||||
#define FSL_SAI_CR4_FSD_MSTR BIT(0)
|
#define FSL_SAI_CR4_FSD_MSTR BIT(0)
|
||||||
|
|
||||||
/* SAI Transmit and Recieve Configuration 5 Register */
|
/* 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(x) (((x) - 1) << 24)
|
||||||
#define FSL_SAI_CR5_WNW_MASK (0x1f << 24)
|
#define FSL_SAI_CR5_WNW_MASK (0x1f << 24)
|
||||||
#define FSL_SAI_CR5_W0W(x) (((x) - 1) << 16)
|
#define FSL_SAI_CR5_W0W(x) (((x) - 1) << 16)
|
||||||
|
|
@ -100,12 +99,11 @@
|
||||||
#define FSL_SAI_MAXBURST_RX 6
|
#define FSL_SAI_MAXBURST_RX 6
|
||||||
|
|
||||||
struct fsl_sai {
|
struct fsl_sai {
|
||||||
struct clk *clk;
|
struct regmap *regmap;
|
||||||
|
|
||||||
void __iomem *base;
|
|
||||||
|
|
||||||
bool big_endian_regs;
|
bool big_endian_regs;
|
||||||
bool big_endian_data;
|
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_rx;
|
||||||
struct snd_dmaengine_dai_dma_data dma_params_tx;
|
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);
|
struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai);
|
||||||
|
|
||||||
dai->playback_dma_data = &spdif_private->dma_params_tx;
|
snd_soc_dai_init_dma_data(dai, &spdif_private->dma_params_tx,
|
||||||
dai->capture_dma_data = &spdif_private->dma_params_rx;
|
&spdif_private->dma_params_rx);
|
||||||
|
|
||||||
snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls));
|
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_bits = 32,
|
||||||
.reg_stride = 4,
|
.reg_stride = 4,
|
||||||
.val_bits = 32,
|
.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));
|
memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai));
|
||||||
spdif_priv->cpu_dai_drv.name = spdif_priv->name;
|
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 */
|
/* Get the addresses and IRQ */
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
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,
|
ret = imx_pcm_preallocate_dma_buffer(pcm,
|
||||||
SNDRV_PCM_STREAM_PLAYBACK);
|
SNDRV_PCM_STREAM_PLAYBACK);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
|
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
|
||||||
ret = imx_pcm_preallocate_dma_buffer(pcm,
|
ret = imx_pcm_preallocate_dma_buffer(pcm,
|
||||||
SNDRV_PCM_STREAM_CAPTURE);
|
SNDRV_PCM_STREAM_CAPTURE);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
return 0;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ssi_irq = 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_codec *codec = rtd->codec;
|
||||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
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 */
|
/* Headphone jack detection */
|
||||||
snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
|
snd_soc_jack_new(codec, "Headphone", SND_JACK_HEADPHONE, &hp_jack);
|
||||||
snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
|
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,
|
.owner = THIS_MODULE,
|
||||||
.dai_link = &wm1133_ev1_dai,
|
.dai_link = &wm1133_ev1_dai,
|
||||||
.num_links = 1,
|
.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;
|
static struct platform_device *wm1133_ev1_snd_device;
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ config SND_OMAP_SOC_OSK5912
|
||||||
tristate "SoC Audio support for omap osk5912"
|
tristate "SoC Audio support for omap osk5912"
|
||||||
depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C
|
depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C
|
||||||
select SND_OMAP_SOC_MCBSP
|
select SND_OMAP_SOC_MCBSP
|
||||||
select SND_SOC_TLV320AIC23
|
select SND_SOC_TLV320AIC23_I2C
|
||||||
help
|
help
|
||||||
Say Y if you want to add support for SoC audio on osk5912.
|
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"
|
tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
|
||||||
depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
|
depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
|
||||||
select SND_OMAP_SOC_MCBSP
|
select SND_OMAP_SOC_MCBSP
|
||||||
select SND_SOC_TLV320AIC23
|
select SND_SOC_TLV320AIC23_I2C
|
||||||
help
|
help
|
||||||
Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
|
Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
|
||||||
EVM.
|
EVM.
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23
|
||||||
tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
|
tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
|
||||||
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
|
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
|
||||||
select SND_S3C24XX_I2S
|
select SND_S3C24XX_I2S
|
||||||
select SND_SOC_TLV320AIC23
|
select SND_SOC_TLV320AIC23_I2C
|
||||||
select SND_SOC_SAMSUNG_SIMTEC
|
select SND_SOC_SAMSUNG_SIMTEC
|
||||||
|
|
||||||
config SND_SOC_SAMSUNG_SIMTEC_HERMES
|
config SND_SOC_SAMSUNG_SIMTEC_HERMES
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ config SND_SOC_TEGRA_TRIMSLICE
|
||||||
tristate "SoC Audio support for TrimSlice board"
|
tristate "SoC Audio support for TrimSlice board"
|
||||||
depends on SND_SOC_TEGRA && I2C
|
depends on SND_SOC_TEGRA && I2C
|
||||||
select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
|
select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
|
||||||
select SND_SOC_TLV320AIC23
|
select SND_SOC_TLV320AIC23_I2C
|
||||||
help
|
help
|
||||||
Say Y or M here if you want to add support for SoC audio on the
|
Say Y or M here if you want to add support for SoC audio on the
|
||||||
TrimSlice platform.
|
TrimSlice platform.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue