]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
Merge remote-tracking branches 'asoc/topic/dwc', 'asoc/topic/es8328', 'asoc/topic...
authorMark Brown <broonie@kernel.org>
Sun, 19 Feb 2017 16:36:23 +0000 (16:36 +0000)
committerMark Brown <broonie@kernel.org>
Sun, 19 Feb 2017 16:36:23 +0000 (16:36 +0000)
13 files changed:
Documentation/devicetree/bindings/sound/es8328.txt
include/sound/soc.h
sound/soc/codecs/Kconfig
sound/soc/codecs/es8328-i2c.c
sound/soc/codecs/es8328.c
sound/soc/dwc/designware_i2s.c
sound/soc/dwc/designware_pcm.c
sound/soc/dwc/local.h
sound/soc/fsl/efika-audio-fabric.c
sound/soc/fsl/fsl_sai.c
sound/soc/fsl/mpc5200_psc_ac97.c
sound/soc/fsl/mpc5200_psc_ac97.h [deleted file]
sound/soc/soc-core.c

index 30ea8a318ae98070624f754f563e56ef2c2be5cd..33fbf058c997c65f5afa899df614e7900f5bfe69 100644 (file)
@@ -4,7 +4,7 @@ This device supports both I2C and SPI.
 
 Required properties:
 
-  - compatible : "everest,es8328"
+  - compatible  : Should be "everest,es8328" or "everest,es8388"
   - DVDD-supply : Regulator providing digital core supply voltage 1.8 - 3.6V
   - AVDD-supply : Regulator providing analog supply voltage 3.3V
   - PVDD-supply : Regulator providing digital IO supply voltage 1.8 - 3.6V
index c6cabf3daebea64c310067b91b62bc83d8018a8f..cdfb55f7aedeac2b0ee6a7f5f7b4bf81da123ddf 100644 (file)
@@ -1645,37 +1645,21 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
 int snd_soc_util_init(void);
 void snd_soc_util_exit(void);
 
-#define snd_soc_of_parse_card_name(card, propname) \
-       snd_soc_of_parse_card_name_from_node(card, NULL, propname)
-int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
-                                        struct device_node *np,
-                                        const char *propname);
-#define snd_soc_of_parse_audio_simple_widgets(card, propname)\
-       snd_soc_of_parse_audio_simple_widgets_from_node(card, NULL, propname)
-int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
-                                                   struct device_node *np,
-                                                   const char *propname);
-
+int snd_soc_of_parse_card_name(struct snd_soc_card *card,
+                              const char *propname);
+int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
+                                         const char *propname);
 int snd_soc_of_parse_tdm_slot(struct device_node *np,
                              unsigned int *tx_mask,
                              unsigned int *rx_mask,
                              unsigned int *slots,
                              unsigned int *slot_width);
-#define snd_soc_of_parse_audio_prefix(card, codec_conf, of_node, propname) \
-       snd_soc_of_parse_audio_prefix_from_node(card, NULL, codec_conf, \
-                                               of_node, propname)
-void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card,
-                                  struct device_node *np,
+void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
                                   struct snd_soc_codec_conf *codec_conf,
                                   struct device_node *of_node,
                                   const char *propname);
-
-#define snd_soc_of_parse_audio_routing(card, propname) \
-       snd_soc_of_parse_audio_routing_from_node(card, NULL, propname)
-int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
-                                            struct device_node *np,
-                                            const char *propname);
-
+int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
+                                  const char *propname);
 unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
                                     const char *prefix,
                                     struct device_node **bitclkmaster,
index 928baa69de91e2c04c64f89b5c1f8352eb0d42f5..e00ba806ef86a36af60c5af96f022351b8f4c7ca 100644 (file)
@@ -525,14 +525,16 @@ config SND_SOC_HDMI_CODEC
        select HDMI
 
 config SND_SOC_ES8328
-       tristate "Everest Semi ES8328 CODEC"
+       tristate
 
 config SND_SOC_ES8328_I2C
-       tristate
+       tristate "Everest Semi ES8328 CODEC (I2C)"
+       depends on I2C
        select SND_SOC_ES8328
 
 config SND_SOC_ES8328_SPI
-       tristate
+       tristate "Everest Semi ES8328 CODEC (SPI)"
+       depends on SPI_MASTER
        select SND_SOC_ES8328
 
 config SND_SOC_GTM601
index 2d05b5d3a6ce7fdc3531f5c322853dbb1a0ca63e..318ab28c5351fcd198603b71b427e6972bbc43c5 100644 (file)
 
 static const struct i2c_device_id es8328_id[] = {
        { "es8328", 0 },
+       { "es8388", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, es8328_id);
 
 static const struct of_device_id es8328_of_match[] = {
        { .compatible = "everest,es8328", },
+       { .compatible = "everest,es8388", },
        { }
 };
 MODULE_DEVICE_TABLE(of, es8328_of_match);
index 37722194b107e8a733bb124be480ff46b63749ef..3f84fbd071e275e52d8c004ae10d7474035c1fc7 100644 (file)
@@ -589,9 +589,21 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
        u8 dac_mode = 0;
        u8 adc_mode = 0;
 
-       /* set master/slave audio interface */
-       if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBM_CFM)
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               /* Master serial port mode, with BCLK generated automatically */
+               snd_soc_update_bits(codec, ES8328_MASTERMODE,
+                                   ES8328_MASTERMODE_MSC,
+                                   ES8328_MASTERMODE_MSC);
+               break;
+       case SND_SOC_DAIFMT_CBS_CFS:
+               /* Slave serial port mode */
+               snd_soc_update_bits(codec, ES8328_MASTERMODE,
+                                   ES8328_MASTERMODE_MSC, 0);
+               break;
+       default:
                return -EINVAL;
+       }
 
        /* interface format */
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -620,10 +632,6 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
        snd_soc_update_bits(codec, ES8328_ADCCONTROL4,
                        ES8328_ADCCONTROL4_ADCFORMAT_MASK, adc_mode);
 
-       /* Master serial port mode, with BCLK generated automatically */
-       snd_soc_update_bits(codec, ES8328_MASTERMODE,
-                       ES8328_MASTERMODE_MSC, ES8328_MASTERMODE_MSC);
-
        return 0;
 }
 
index bdf8398cbc81b68b445f202636e8949db5e5cae5..9c46e411202649a31c5a597cebd4af83e2826ce7 100644 (file)
@@ -121,9 +121,14 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
                        irq_valid = true;
                }
 
-               /* Data available. Record mode not supported in PIO mode */
-               if (isr[i] & ISR_RXDA)
+               /*
+                * Data available. Retrieve samples from FIFO
+                * NOTE: Only two channels supported
+                */
+               if ((isr[i] & ISR_RXDA) && (i == 0) && dev->use_pio) {
+                       dw_pcm_pop_rx(dev);
                        irq_valid = true;
+               }
 
                /* Error Handling: TX */
                if (isr[i] & ISR_TXFO) {
index 4a83a22fa3cb148cccd50780cc68281c46e675f4..459ec861e6b6c84c04a7597dde059131523d6654 100644 (file)
@@ -41,10 +41,33 @@ static unsigned int dw_pcm_tx_##sample_bits(struct dw_i2s_dev *dev, \
        return tx_ptr; \
 }
 
+#define dw_pcm_rx_fn(sample_bits) \
+static unsigned int dw_pcm_rx_##sample_bits(struct dw_i2s_dev *dev, \
+               struct snd_pcm_runtime *runtime, unsigned int rx_ptr, \
+               bool *period_elapsed) \
+{ \
+       u##sample_bits (*p)[2] = (void *)runtime->dma_area; \
+       unsigned int period_pos = rx_ptr % runtime->period_size; \
+       int i; \
+\
+       for (i = 0; i < dev->fifo_th; i++) { \
+               p[rx_ptr][0] = ioread32(dev->i2s_base + LRBR_LTHR(0)); \
+               p[rx_ptr][1] = ioread32(dev->i2s_base + RRBR_RTHR(0)); \
+               period_pos++; \
+               if (++rx_ptr >= runtime->buffer_size) \
+                       rx_ptr = 0; \
+       } \
+       *period_elapsed = period_pos >= runtime->period_size; \
+       return rx_ptr; \
+}
+
 dw_pcm_tx_fn(16);
 dw_pcm_tx_fn(32);
+dw_pcm_rx_fn(16);
+dw_pcm_rx_fn(32);
 
 #undef dw_pcm_tx_fn
+#undef dw_pcm_rx_fn
 
 static const struct snd_pcm_hardware dw_pcm_hardware = {
        .info = SNDRV_PCM_INFO_INTERLEAVED |
@@ -57,6 +80,7 @@ static const struct snd_pcm_hardware dw_pcm_hardware = {
        .rate_min = 32000,
        .rate_max = 48000,
        .formats = SNDRV_PCM_FMTBIT_S16_LE |
+               SNDRV_PCM_FMTBIT_S24_LE |
                SNDRV_PCM_FMTBIT_S32_LE,
        .channels_min = 2,
        .channels_max = 2,
@@ -68,27 +92,51 @@ static const struct snd_pcm_hardware dw_pcm_hardware = {
        .fifo_size = 16,
 };
 
-void dw_pcm_push_tx(struct dw_i2s_dev *dev)
+static void dw_pcm_transfer(struct dw_i2s_dev *dev, bool push)
 {
-       struct snd_pcm_substream *tx_substream;
-       bool tx_active, period_elapsed;
+       struct snd_pcm_substream *substream;
+       bool active, period_elapsed;
 
        rcu_read_lock();
-       tx_substream = rcu_dereference(dev->tx_substream);
-       tx_active = tx_substream && snd_pcm_running(tx_substream);
-       if (tx_active) {
-               unsigned int tx_ptr = READ_ONCE(dev->tx_ptr);
-               unsigned int new_tx_ptr = dev->tx_fn(dev, tx_substream->runtime,
-                               tx_ptr, &period_elapsed);
-               cmpxchg(&dev->tx_ptr, tx_ptr, new_tx_ptr);
+       if (push)
+               substream = rcu_dereference(dev->tx_substream);
+       else
+               substream = rcu_dereference(dev->rx_substream);
+       active = substream && snd_pcm_running(substream);
+       if (active) {
+               unsigned int ptr;
+               unsigned int new_ptr;
+
+               if (push) {
+                       ptr = READ_ONCE(dev->tx_ptr);
+                       new_ptr = dev->tx_fn(dev, substream->runtime, ptr,
+                                       &period_elapsed);
+                       cmpxchg(&dev->tx_ptr, ptr, new_ptr);
+               } else {
+                       ptr = READ_ONCE(dev->rx_ptr);
+                       new_ptr = dev->rx_fn(dev, substream->runtime, ptr,
+                                       &period_elapsed);
+                       cmpxchg(&dev->rx_ptr, ptr, new_ptr);
+               }
 
                if (period_elapsed)
-                       snd_pcm_period_elapsed(tx_substream);
+                       snd_pcm_period_elapsed(substream);
        }
        rcu_read_unlock();
 }
+
+void dw_pcm_push_tx(struct dw_i2s_dev *dev)
+{
+       dw_pcm_transfer(dev, true);
+}
 EXPORT_SYMBOL_GPL(dw_pcm_push_tx);
 
+void dw_pcm_pop_rx(struct dw_i2s_dev *dev)
+{
+       dw_pcm_transfer(dev, false);
+}
+EXPORT_SYMBOL_GPL(dw_pcm_pop_rx);
+
 static int dw_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
@@ -126,20 +174,18 @@ static int dw_pcm_hw_params(struct snd_pcm_substream *substream,
        switch (params_format(hw_params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
                dev->tx_fn = dw_pcm_tx_16;
+               dev->rx_fn = dw_pcm_rx_16;
                break;
+       case SNDRV_PCM_FORMAT_S24_LE:
        case SNDRV_PCM_FORMAT_S32_LE:
                dev->tx_fn = dw_pcm_tx_32;
+               dev->rx_fn = dw_pcm_rx_32;
                break;
        default:
                dev_err(dev->dev, "invalid format\n");
                return -EINVAL;
        }
 
-       if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
-               dev_err(dev->dev, "only playback is available\n");
-               return -EINVAL;
-       }
-
        ret = snd_pcm_lib_malloc_pages(substream,
                        params_buffer_bytes(hw_params));
        if (ret < 0)
@@ -163,13 +209,21 @@ static int dw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               WRITE_ONCE(dev->tx_ptr, 0);
-               rcu_assign_pointer(dev->tx_substream, substream);
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+                       WRITE_ONCE(dev->tx_ptr, 0);
+                       rcu_assign_pointer(dev->tx_substream, substream);
+               } else {
+                       WRITE_ONCE(dev->rx_ptr, 0);
+                       rcu_assign_pointer(dev->rx_substream, substream);
+               }
                break;
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               rcu_assign_pointer(dev->tx_substream, NULL);
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       rcu_assign_pointer(dev->tx_substream, NULL);
+               else
+                       rcu_assign_pointer(dev->rx_substream, NULL);
                break;
        default:
                ret = -EINVAL;
@@ -183,7 +237,12 @@ static snd_pcm_uframes_t dw_pcm_pointer(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct dw_i2s_dev *dev = runtime->private_data;
-       snd_pcm_uframes_t pos = READ_ONCE(dev->tx_ptr);
+       snd_pcm_uframes_t pos;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               pos = READ_ONCE(dev->tx_ptr);
+       else
+               pos = READ_ONCE(dev->rx_ptr);
 
        return pos < runtime->buffer_size ? pos : 0;
 }
index 68afd7577343f4d64a74eb26956edfb00053db3f..91dc70a826f8a28ef6063a9ffec859cfbd385540 100644 (file)
@@ -105,20 +105,27 @@ struct dw_i2s_dev {
        struct i2s_clk_config_data config;
        int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
 
-       /* data related to PIO transfers (TX) */
+       /* data related to PIO transfers */
        bool use_pio;
        struct snd_pcm_substream __rcu *tx_substream;
+       struct snd_pcm_substream __rcu *rx_substream;
        unsigned int (*tx_fn)(struct dw_i2s_dev *dev,
                        struct snd_pcm_runtime *runtime, unsigned int tx_ptr,
                        bool *period_elapsed);
+       unsigned int (*rx_fn)(struct dw_i2s_dev *dev,
+                       struct snd_pcm_runtime *runtime, unsigned int rx_ptr,
+                       bool *period_elapsed);
        unsigned int tx_ptr;
+       unsigned int rx_ptr;
 };
 
 #if IS_ENABLED(CONFIG_SND_DESIGNWARE_PCM)
 void dw_pcm_push_tx(struct dw_i2s_dev *dev);
+void dw_pcm_pop_rx(struct dw_i2s_dev *dev);
 int dw_pcm_register(struct platform_device *pdev);
 #else
 void dw_pcm_push_tx(struct dw_i2s_dev *dev) { }
+void dw_pcm_pop_rx(struct dw_i2s_dev *dev) { }
 int dw_pcm_register(struct platform_device *pdev)
 {
        return -EINVAL;
index f200d1cfc4bd4d854b425f220c5b8e3bb49b22b1..667f4215dfc0f07dd58b02c92e7dc542ac5eb1f5 100644 (file)
@@ -26,7 +26,6 @@
 #include <sound/soc.h>
 
 #include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
 
 #define DRV_NAME "efika-audio-fabric"
 
index 9fadf7e31c5f86459efc0b70fb1674f45da5a289..18e5ce81527d223b98d832fcd7ab6d5ee7ee7879 100644 (file)
@@ -668,7 +668,7 @@ static struct snd_soc_dai_driver fsl_sai_dai = {
        .playback = {
                .stream_name = "CPU-Playback",
                .channels_min = 1,
-               .channels_max = 2,
+               .channels_max = 32,
                .rate_min = 8000,
                .rate_max = 192000,
                .rates = SNDRV_PCM_RATE_KNOT,
@@ -677,7 +677,7 @@ static struct snd_soc_dai_driver fsl_sai_dai = {
        .capture = {
                .stream_name = "CPU-Capture",
                .channels_min = 1,
-               .channels_max = 2,
+               .channels_max = 32,
                .rate_min = 8000,
                .rate_max = 192000,
                .rates = SNDRV_PCM_RATE_KNOT,
index 243700cc29e618417d2e3561f6c554031229d531..07ee355ee385b16585418025720dfb5a941ab904 100644 (file)
@@ -25,7 +25,6 @@
 #include <asm/mpc52xx_psc.h>
 
 #include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
 
 #define DRV_NAME "mpc5200-psc-ac97"
 
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.h b/sound/soc/fsl/mpc5200_psc_ac97.h
deleted file mode 100644 (file)
index e881e78..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Freescale MPC5200 PSC in AC97 mode
- * ALSA SoC Digital Audio Interface (DAI) driver
- *
- */
-
-#ifndef __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__
-#define __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__
-
-#define MPC5200_AC97_NORMAL 0
-#define MPC5200_AC97_SPDIF 1
-
-#endif /* __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__ */
index 175c8227de2c85a6cf1e444b0c59b8575ae4987c..a110d3987d4ae912b46c57f2f36f258b985b56e5 100644 (file)
@@ -3675,10 +3675,10 @@ found:
 EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
 
 /* Retrieve a card's name from device tree */
-int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
-                                        struct device_node *np,
-                                        const char *propname)
+int snd_soc_of_parse_card_name(struct snd_soc_card *card,
+                              const char *propname)
 {
+       struct device_node *np;
        int ret;
 
        if (!card->dev) {
@@ -3686,8 +3686,7 @@ int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
                return -EINVAL;
        }
 
-       if (!np)
-               np = card->dev->of_node;
+       np = card->dev->of_node;
 
        ret = of_property_read_string_index(np, propname, 0, &card->name);
        /*
@@ -3704,7 +3703,7 @@ int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name_from_node);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name);
 
 static const struct snd_soc_dapm_widget simple_widgets[] = {
        SND_SOC_DAPM_MIC("Microphone", NULL),
@@ -3713,17 +3712,14 @@ static const struct snd_soc_dapm_widget simple_widgets[] = {
        SND_SOC_DAPM_SPK("Speaker", NULL),
 };
 
-int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
-                                         struct device_node *np,
+int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
                                          const char *propname)
 {
+       struct device_node *np = card->dev->of_node;
        struct snd_soc_dapm_widget *widgets;
        const char *template, *wname;
        int i, j, num_widgets, ret;
 
-       if (!np)
-               np = card->dev->of_node;
-
        num_widgets = of_property_count_strings(np, propname);
        if (num_widgets < 0) {
                dev_err(card->dev,
@@ -3794,7 +3790,7 @@ int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets_from_node);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets);
 
 static int snd_soc_of_get_slot_mask(struct device_node *np,
                                    const char *prop_name,
@@ -3850,18 +3846,15 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot);
 
-void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card,
-                                  struct device_node *np,
+void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
                                   struct snd_soc_codec_conf *codec_conf,
                                   struct device_node *of_node,
                                   const char *propname)
 {
+       struct device_node *np = card->dev->of_node;
        const char *str;
        int ret;
 
-       if (!np)
-               np = card->dev->of_node;
-
        ret = of_property_read_string(np, propname, &str);
        if (ret < 0) {
                /* no prefix is not error */
@@ -3871,19 +3864,16 @@ void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card,
        codec_conf->of_node     = of_node;
        codec_conf->name_prefix = str;
 }
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix_from_node);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_prefix);
 
-int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
-                                  struct device_node *np,
+int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
                                   const char *propname)
 {
+       struct device_node *np = card->dev->of_node;
        int num_routes;
        struct snd_soc_dapm_route *routes;
        int i, ret;
 
-       if (!np)
-               np = card->dev->of_node;
-
        num_routes = of_property_count_strings(np, propname);
        if (num_routes < 0 || num_routes & 1) {
                dev_err(card->dev,
@@ -3930,7 +3920,7 @@ int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing_from_node);
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
 
 unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
                                     const char *prefix,