]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
Merge remote-tracking branches 'asoc/topic/da7213', 'asoc/topic/da732x', 'asoc/topic...
authorMark Brown <broonie@linaro.org>
Wed, 12 Mar 2014 23:04:22 +0000 (23:04 +0000)
committerMark Brown <broonie@linaro.org>
Wed, 12 Mar 2014 23:04:22 +0000 (23:04 +0000)
30 files changed:
Documentation/devicetree/bindings/sound/da9055.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
Documentation/devicetree/bindings/sound/eukrea-tlv320.txt [new file with mode: 0644]
Documentation/devicetree/bindings/sound/fsl,esai.txt
Documentation/devicetree/bindings/sound/fsl,spdif.txt
include/linux/platform_data/davinci_asp.h
sound/soc/atmel/Kconfig
sound/soc/cirrus/Kconfig
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/da7213.c
sound/soc/codecs/da732x.c
sound/soc/codecs/da9055.c
sound/soc/codecs/tlv320aic23-i2c.c [new file with mode: 0644]
sound/soc/codecs/tlv320aic23-spi.c [new file with mode: 0644]
sound/soc/codecs/tlv320aic23.c
sound/soc/codecs/tlv320aic23.h
sound/soc/davinci/davinci-evm.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/fsl/Kconfig
sound/soc/fsl/eukrea-tlv320.c
sound/soc/fsl/fsl_esai.c
sound/soc/fsl/fsl_sai.c
sound/soc/fsl/fsl_sai.h
sound/soc/fsl/fsl_spdif.c
sound/soc/fsl/imx-pcm-fiq.c
sound/soc/fsl/wm1133-ev1.c
sound/soc/omap/Kconfig
sound/soc/samsung/Kconfig
sound/soc/tegra/Kconfig

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