AnsweredAssumed Answered

I2S 2-channel mems microphone

Question asked by Jarrod Cook on May 4, 2018
Latest reply on Jun 5, 2018 by Jarrod Cook

Hello,

 

I have 2 I2S microphones (SPH0645LM4H) hooked up to an i.MX6 Solo.  These mic's transmit I2S audio data on either the low Frame Clock or the High Frame Clock of the I2S based on a select pin, i have one pulled either way so that i essentially have stereo microphones.  I have everything setup and working and i can capture audio data but i only get the left channel, the right channels i just silence with a little white noise.  I can't seem to figure out what the problem is, I can see the data on the scope and everything looks great, i see left channel data during the low frame clock and right channel during the high frame clock. 

 

They are connected as follows:

 

I2S_CLK -> CSI0_DAT4 -> AUD3_TXC

I2S_WS -> CSI0_DAT6 -> AUD3_TXFS

I2S_DATA -> CSI0_DAT7 -> AUD3_RXD

 

And here is how the device tree is setup:

 

pinctrl_micmux: micmuxgrp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0
MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0
MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0
>;
};

 

sound {
compatible = "fsl,imx-audio-sph0645",
"fsl,imx-mic-sph0645";
model = "sph0645-audio";
ssi-controller = <&ssi2>;
mux-int-port = <2>;
mux-ext-port = <3>;
};

 

&audmux {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_micmux>;
status = "okay";
};

 

&ssi2 {
fsl,mode = "i2s-master";
assigned-clocks = <&clks IMX6QDL_CLK_SSI2_SEL>,
<&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>;
assigned-clock-rates = <0>;
status = "okay";
};

 

 

And imx-audio-sph0645 is a small driver i wrote just to try and get this working, i have attached the whole file but here are the important parts:

 

 

static int imx_audmux_config(int slave, int master)
{
unsigned int ptcr, pdcr;
slave = slave - 1;
master = master - 1;

ptcr = IMX_AUDMUX_V2_PTCR_SYN |
IMX_AUDMUX_V2_PTCR_TFSDIR |
IMX_AUDMUX_V2_PTCR_TFSEL(slave) |
IMX_AUDMUX_V2_PTCR_TCLKDIR |
IMX_AUDMUX_V2_PTCR_TCSEL(slave);
pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(slave);
imx_audmux_v2_configure_port(master, ptcr, pdcr);

/*
* According to RM, RCLKDIR and SYN should not be changed at same time.
* So separate to two step for configuring this port.
*/
ptcr |= IMX_AUDMUX_V2_PTCR_RFSDIR |
IMX_AUDMUX_V2_PTCR_RFSEL(slave) |
IMX_AUDMUX_V2_PTCR_RCLKDIR |
IMX_AUDMUX_V2_PTCR_RCSEL(slave);
imx_audmux_v2_configure_port(master, ptcr, pdcr);

ptcr = IMX_AUDMUX_V2_PTCR_SYN;
pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(master);
imx_audmux_v2_configure_port(slave, ptcr, pdcr);

return 0;
}

static int imx_sph0645_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
u32 channels = 2; //ALWAYS 2 CHANNELS params_channels(params);
u32 rate = params_rate(params);
u32 bclk = rate * channels * 32;
int ret = 0;

/* set cpu DAI configuration */
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
if (ret) {
dev_err(cpu_dai->dev, "failed to set dai fmt\n");
return ret;
}

ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 3, 2, 32);
if (ret) {
dev_err(cpu_dai->dev, "failed to set dai tdm slot\n");
return ret;
}

ret = snd_soc_dai_set_sysclk(cpu_dai, 0, bclk, SND_SOC_CLOCK_OUT);
if (ret)
dev_err(cpu_dai->dev, "failed to set cpu sysclk\n");

return ret;
}

 

Any idea what I am doing wrong??? Like i said on an oscilloscope the signals look great and i get great left channel audio, but nothing on the right : /.  Here is how I am recording:

 

arecord -c 2 -d 5 -f S32 -r 48000 -v /home/root/test.wav

 

Thanks,

Jarrod

Attachments

Outcomes