This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit d98df37f3595b4c585a2685b7f39021c2b62bd01
Author: Tiago Medicci Serrano <[email protected]>
AuthorDate: Wed Oct 26 13:20:34 2022 -0300

    xtensa/esp32s2: add i2s_mclkfrequency to set master clock on I2S
---
 arch/xtensa/src/esp32s2/esp32s2_i2s.c | 54 +++++++++++++++++++++++++++++++----
 1 file changed, 49 insertions(+), 5 deletions(-)

diff --git a/arch/xtensa/src/esp32s2/esp32s2_i2s.c 
b/arch/xtensa/src/esp32s2/esp32s2_i2s.c
index 50ea4c13a0..24e8753b95 100644
--- a/arch/xtensa/src/esp32s2/esp32s2_i2s.c
+++ b/arch/xtensa/src/esp32s2/esp32s2_i2s.c
@@ -229,6 +229,7 @@ struct esp32s2_i2s_s
   mutex_t           lock;       /* Assures mutually exclusive access */
   uint32_t          rate;       /* I2S actual configured sample-rate */
   uint32_t          data_width; /* I2S actual configured data_width */
+  uint32_t          mclk_freq;  /* I2S actual master clock */
   int               cpuint;     /* I2S interrupt ID */
   uint8_t           cpu;        /* CPU ID */
 
@@ -288,6 +289,8 @@ static void     i2s_tx_schedule(struct esp32s2_i2s_s *priv,
 
 /* I2S methods (and close friends) */
 
+static uint32_t esp32s2_i2s_mclkfrequency(struct i2s_dev_s *dev,
+                                          uint32_t frequency);
 static uint32_t esp32s2_i2s_txsamplerate(struct i2s_dev_s *dev,
                                          uint32_t rate);
 static uint32_t esp32s2_i2s_txdatawidth(struct i2s_dev_s *dev, int bits);
@@ -302,9 +305,10 @@ static int      esp32s2_i2s_send(struct i2s_dev_s *dev,
 
 static const struct i2s_ops_s g_i2sops =
 {
-  .i2s_txsamplerate = esp32s2_i2s_txsamplerate,
-  .i2s_txdatawidth  = esp32s2_i2s_txdatawidth,
-  .i2s_send         = esp32s2_i2s_send,
+  .i2s_txsamplerate   = esp32s2_i2s_txsamplerate,
+  .i2s_txdatawidth    = esp32s2_i2s_txdatawidth,
+  .i2s_send           = esp32s2_i2s_send,
+  .i2s_mclkfrequency  = esp32s2_i2s_mclkfrequency,
 };
 
 #ifdef CONFIG_ESP32S2_I2S
@@ -319,7 +323,7 @@ static const struct esp32s2_i2s_config_s 
esp32s2_i2s0_config =
   .data_width       = CONFIG_ESP32S2_I2S_DATA_BIT_WIDTH,
   .rate             = CONFIG_ESP32S2_I2S_SAMPLE_RATE,
   .total_slot       = 2,
-  .mclk_multiple    = I2S_MCLK_MULTIPLE_384,
+  .mclk_multiple    = I2S_MCLK_MULTIPLE_256,
   .tx_en            = I2S_TX_ENABLED,
   .rx_en            = I2S_RX_ENABLED,
 #ifdef CONFIG_ESP32S2_I2S_MCLK
@@ -1016,6 +1020,10 @@ static void i2s_configure(struct esp32s2_i2s_s *priv)
 
       modifyreg32(I2S_FIFO_CONF_REG, 0, I2S_TX_FIFO_MOD_FORCE_EN);
 
+      esp32s2_i2s_mclkfrequency((struct i2s_dev_s *)priv,
+                                (priv->config->rate *
+                                priv->config->mclk_multiple));
+
       esp32s2_i2s_txsamplerate((struct i2s_dev_s *)priv, priv->config->rate);
     }
 
@@ -1107,6 +1115,42 @@ static int esp32s2_i2s_interrupt(int irq, void *context, 
void *arg)
   return 0;
 }
 
+/****************************************************************************
+ * Name: esp32s2_i2s_mclkfrequency
+ *
+ * Description:
+ *   Set the master clock frequency. Usually, the MCLK is a multiple of the
+ *   sample rate. Most of the audio codecs require setting specific MCLK
+ *   frequency according to the sample rate.
+ *
+ * Input Parameters:
+ *   dev        - Device-specific state data
+ *   frequency  - The I2S master clock's frequency
+ *
+ * Returned Value:
+ *   Returns the resulting master clock or a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static uint32_t esp32s2_i2s_mclkfrequency(struct i2s_dev_s *dev,
+                                          uint32_t frequency)
+{
+  struct esp32s2_i2s_s *priv = (struct esp32s2_i2s_s *)dev;
+
+  /* Check if the master clock frequency is beyond the highest possible
+   * value and return an error.
+   */
+
+  if (frequency >= (I2S_LL_BASE_CLK / 2))
+    {
+      return -EINVAL;
+    }
+
+  priv->mclk_freq = frequency;
+
+  return frequency;
+}
+
 /****************************************************************************
  * Name: esp32s2_i2s_txsamplerate
  *
@@ -1157,7 +1201,7 @@ static uint32_t esp32s2_i2s_txsamplerate(struct i2s_dev_s 
*dev,
   if (priv->config->role == I2S_ROLE_MASTER)
     {
       bclk = rate * priv->config->total_slot * priv->data_width;
-      mclk = rate * priv->config->mclk_multiple;
+      mclk = priv->mclk_freq;
       bclk_div = mclk / bclk;
     }
   else

Reply via email to