audio: add i2s capture function and fix pinctrl error
authorPeipeng Zhao <peipeng.zhao@amlogic.com>
Wed, 19 Apr 2017 06:34:27 +0000 (14:34 +0800)
committerPeipeng Zhao <peipeng.zhao@amlogic.com>
Wed, 19 Apr 2017 07:39:16 +0000 (15:39 +0800)
PD#138714: fix i2s in error

1. add aml_i2s_copy_capture for 8 channels
2. fix i2s pinctrl define error
3. add 8channel mic board d601 function on P400/P401 dts

Change-Id: I7b289e9926bded95f2a4e9a24b756363a94ba8dd
Signed-off-by: Peipeng Zhao <peipeng.zhao@amlogic.com>
12 files changed:
arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts
arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts
arch/arm64/boot/dts/amlogic/gxl_p400_2g.dts
arch/arm64/boot/dts/amlogic/gxl_p401_2g.dts
arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts
arch/arm64/boot/dts/amlogic/gxm_skt.dts
drivers/amlogic/pinctrl/pinctrl_gxl.c
scripts/amlogic/mk_dtb_gx.sh
sound/soc/amlogic/aml_i2s.c
sound/soc/amlogic/aml_i2s_dai.c
sound/soc/amlogic/aml_i2s_dai.h
sound/soc/codecs/amlogic/dummy_codec.c

index 9640d83..c762d19 100644 (file)
                        "top_level",
                        "aoclk",
                        "aud_in";
+               i2s_pos_sync = <0>;
                /*DMIC;*/  /* I2s Mic or Dmic, default for I2S mic */
        };
        dmic:snd_dmic {
index b59a8a5..f9194d5 100644 (file)
                        "top_level",
                        "aoclk",
                        "aud_in";
+               i2s_pos_sync = <0>;
                /*DMIC;*/  /* I2s Mic or Dmic, default for I2S mic */
        };
        dmic:snd_dmic {
index 263b154..00a5914 100644 (file)
                        "top_level",
                        "aoclk",
                        "aud_in";
+               i2s_pos_sync = <1>;
                /*DMIC;*/  /* I2s Mic or Dmic, default for I2S mic */
        };
        dmic:snd_dmic {
        dummy_codec:dummy{
                #sound-dai-cells = <0>;
                compatible = "amlogic, aml_dummy_codec";
-               status = "disable";
+               status = "okay";
        };
        amlogic_codec:t9015{
                #sound-dai-cells = <0>;
                compatible = "amlogic, aml_codec_T9015";
                reg = <0x0 0xc8832000 0x0 0x14>;
-               status = "okay";
+               status = "disable";
        };
        aml_sound_meson {
                compatible = "aml, meson-snd-card";
                        sound-dai = <&pcm_dai>;
                };
                codec0: codec0 {
-                       sound-dai = <&amlogic_codec>;
+                       sound-dai = <&dummy_codec>;
                };
                codec1: codec1 {
                        sound-dai = <&spdif_codec>;
 &efuse {
        status = "ok";
 };
+       &audio_i2s_pins {
+               mux {
+                       groups = "i2s_am_clk",
+                       "i2s_ao_clk_out",
+                       "i2s_lr_clk_out",
+                       "i2sout_ch01",
+                       "i2sin_ch23",
+                       "i2sin_ch45",
+                       "i2sin_ch67";
+                       function = "i2s";
+               };
+       };
index 9939820..8113ddd 100644 (file)
                        "top_level",
                        "aoclk",
                        "aud_in";
+               i2s_pos_sync = <1>;
                /*DMIC;*/  /* I2s Mic or Dmic, default for I2S mic */
        };
        dmic:snd_dmic {
        dummy_codec:dummy{
                #sound-dai-cells = <0>;
                compatible = "amlogic, aml_dummy_codec";
-               status = "disable";
+               status = "okay";
        };
        amlogic_codec:t9015{
                #sound-dai-cells = <0>;
                compatible = "amlogic, aml_codec_T9015";
                reg = <0x0 0xc8832000 0x0 0x14>;
-               status = "okay";
+               status = "disable";
        };
        aml_sound_meson {
                compatible = "aml, meson-snd-card";
                        sound-dai = <&pcm_dai>;
                };
                codec0: codec0 {
-                       sound-dai = <&amlogic_codec>;
+                       sound-dai = <&dummy_codec>;
                };
                codec1: codec1 {
                        sound-dai = <&spdif_codec>;
 &efuse {
        status = "ok";
 };
+       &audio_i2s_pins {
+               mux {
+                       groups = "i2s_am_clk",
+                       "i2s_ao_clk_out",
+                       "i2s_lr_clk_out",
+                       "i2sout_ch01",
+                       "i2sin_ch23",
+                       "i2sin_ch45",
+                       "i2sin_ch67";
+                       function = "i2s";
+               };
+       };
index 1c7d932..9bb10ac 100644 (file)
                        "top_level",
                        "aoclk",
                        "aud_in";
+               i2s_pos_sync = <0>;
                /*DMIC;*/  /* I2s Mic or Dmic, default for I2S mic */
        };
        dmic:snd_dmic {
index a5a9383..82a46f2 100644 (file)
                        "top_level",
                        "aoclk",
                        "aud_in";
+               i2s_pos_sync = <0>;
                /*DMIC;*/  /* I2s Mic or Dmic, default for I2S mic */
        };
        dmic:snd_dmic {
index 8284843..dd94333 100644 (file)
@@ -290,7 +290,7 @@ static const unsigned int tsin_clk_b_pins[] = { PIN(GPIOZ_3, EE_OFF) };
 static const unsigned int dvp_clk_pins[]       = { PIN(GPIOZ_3, EE_OFF) };
 /*z4*/
 static const unsigned int eth_rxd0_pins[] = { PIN(GPIOZ_4, EE_OFF) };
-static const unsigned int i2cin_ch67_pins[] = { PIN(GPIOZ_4, EE_OFF) };
+static const unsigned int i2sin_ch67_pins[] = { PIN(GPIOZ_4, EE_OFF) };
 static const unsigned int tsin_fail_b_pins[] = { PIN(GPIOZ_4, EE_OFF) };
 static const unsigned int dvp_d2_pins[] = { PIN(GPIOZ_4, EE_OFF) };
 /*z5*/
@@ -539,7 +539,7 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
        GROUP(tsin_clk_b,               3,      16), /*z3*/
        GROUP(dvp_clk,          3,      12), /*z3*/
 
-       GROUP(i2cin_ch67,       3,      27), /*z4*/
+       GROUP(i2sin_ch67,       3,      27), /*z4*/
        GROUP(tsin_fail_b,              3,      15), /*z4*/
        GROUP(dvp_d2,           3,      11), /*z4*/
 
@@ -713,8 +713,8 @@ static struct meson_pmx_group meson_gxl_aobus_groups[] = {
        GROUP(uart_tx_ao_b_0, 0,        24),    /*ao4*/
        GROUP(uart_rx_ao_b_0, 0,        23),    /*ao5*/
 
-       GROUP(spdif_out, 0,     16),
-       GROUP(pwm_ao_b, 0,      18),
+       GROUP(spdif_out, 6,     28), /*H4*/
+       GROUP(pwm_ao_b, 0,      18), /*ao6*/
 
        GROUP(remote_input, 0,  0),       /*ao7*/
        GROUP(remote_output, 0, 21), /*ao7*/
@@ -855,6 +855,7 @@ static const char * const i2c_d_groups[] = {
 
 static const char * const i2s_groups[] = {
        "i2s_am_clk", "i2s_ao_clk_out", "i2s_lr_clk_out", "i2sout_ch01",
+       "i2sin_ch23", "i2sin_ch45", "i2sin_ch67",
 };
 
 static const char * const sdio_groups[] = {
index 20b1d99..8833918 100755 (executable)
@@ -9,3 +9,5 @@ make ARCH=arm64 gxm_skt.dtb || echo "Compile dtb Fail !!"
 make ARCH=arm64 gxl_p212_2g.dtb || echo "Compile dtb Fail !!"
 
 make ARCH=arm64 gxl_p212_1g.dtb || echo "Compile dtb Fail !!"
+
+make ARCH=arm64 gxl_p400_2g.dtb || echo "Compile dtb Fail !!"
index 33f2cb2..a0cdf2b 100644 (file)
@@ -1000,6 +1000,32 @@ static int aml_i2s_copy_capture(struct snd_pcm_runtime *runtime, int channel,
                                }
                                memset(hwbuf, 0, n);
                        }
+               } else if (runtime->channels == 8) {
+                       /* for fifo0 1 ch mode, i2s_ctrl b[13:10]=0xf */
+                       if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
+                               char *hwbuf = runtime->dma_area + offset*2;
+                               int32_t *tfrom = (int32_t *)hwbuf;
+                               int16_t *to = (int16_t *)ubuf;
+
+                               for (j = 0; j < n*2; j += 4) {
+                                       *to++ = (int16_t)(((*tfrom++) >> 8)
+                                                       & 0xffff);
+                               }
+                               memset(hwbuf, 0, n*2);
+                       } else {
+                               /* S24_LE or S32_LE */
+                               char *hwbuf = runtime->dma_area + offset;
+                               int32_t *tfrom = (int32_t *)hwbuf;
+                               int32_t *to = (int32_t *)ubuf;
+
+                               if (runtime->format == SNDRV_PCM_FORMAT_S24_LE)
+                                       r_shift = 0;
+                               for (j = 0; j < n; j += 4) {
+                                       *to++ = (int32_t)((*tfrom++)
+                                                      << r_shift);
+                               }
+                               memset(hwbuf, 0, n);
+                       }
                }
        }
        res = copy_to_user(buf, ubuf, n);
index 9568526..97feeeb 100644 (file)
@@ -47,8 +47,6 @@
 
 struct aml_dai_info dai_info[3] = { {0} };
 
-static int i2s_pos_sync;
-
 /* extern int set_i2s_iec958_samesource(int enable);
  *
  * the I2S hw  and IEC958 PCM output initiation,958 initiation here,
@@ -152,14 +150,16 @@ static int aml_dai_i2s_prepare(struct snd_pcm_substream *substream,
                if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
                        audio_in_i2s_set_buf(runtime->dma_addr,
                                        runtime->dma_bytes * 2,
-                                       0, i2s_pos_sync, i2s->audin_fifo_src,
+                                       0, i2s->i2s_pos_sync,
+                                       i2s->audin_fifo_src,
                                        runtime->channels);
                        memset((void *)runtime->dma_area, 0,
                                        runtime->dma_bytes * 2);
                } else {
                        audio_in_i2s_set_buf(runtime->dma_addr,
                                        runtime->dma_bytes,
-                                       0, i2s_pos_sync, i2s->audin_fifo_src,
+                                       0, i2s->i2s_pos_sync,
+                                       i2s->audin_fifo_src,
                                        runtime->channels);
                        memset((void *)runtime->dma_area, 0,
                                        runtime->dma_bytes);
@@ -245,15 +245,17 @@ static int aml_dai_i2s_hw_params(struct snd_pcm_substream *substream,
 
 static int aml_dai_set_i2s_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
+       struct aml_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+
        if (fmt & SND_SOC_DAIFMT_CBS_CFS)       /* slave mode */
                dai_info[dai->id].i2s_mode = I2S_SLAVE_MODE;
 
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
        case SND_SOC_DAIFMT_NB_NF:
-               i2s_pos_sync = 0;
+               i2s->i2s_pos_sync = 0;
                break;
        case SND_SOC_DAIFMT_IB_NF:
-               i2s_pos_sync = 1;
+               i2s->i2s_pos_sync = 1;
                break;
        default:
                return -EINVAL;
@@ -396,6 +398,15 @@ static int aml_i2s_dai_probe(struct platform_device *pdev)
                dev_info(&pdev->dev, "I2S Mic is in platform!\n");
        }
 
+       ret =
+           of_property_read_u32((&pdev->dev)->of_node, "i2s_pos_sync",
+                                &i2s->i2s_pos_sync);
+
+       if (ret < 0)
+               i2s->i2s_pos_sync = 0;
+
+       dev_info(&pdev->dev, "i2s_pos_sync is %d\n", i2s->i2s_pos_sync);
+
        ret = snd_soc_register_component(&pdev->dev, &aml_component,
                                          aml_i2s_dai, ARRAY_SIZE(aml_i2s_dai));
        if (ret) {
index eee31d2..0e2c94d 100644 (file)
@@ -25,6 +25,7 @@ struct aml_i2s {
        int old_samplerate;
        bool disable_clk_suspend;
        int audin_fifo_src;
+       int i2s_pos_sync;
 };
 
 #endif
index 89b7974..ddc8320 100644 (file)
@@ -91,7 +91,7 @@ struct snd_soc_dai_driver dummy_codec_dai = {
        .capture = {
                    .stream_name = "HIFI Capture",
                    .channels_min = 1,
-                   .channels_max = 2,
+                   .channels_max = 8,
                    .rates = DUMMY_CODEC_RATES,
                    .formats = DUMMY_CODEC_FORMATS,
                    },