i.MX28 (i.MX286) and SGTL5000 audio recording issue

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX28 (i.MX286) and SGTL5000 audio recording issue

3,695 Views
gianlucarenzi71
Contributor II

Hello to everybody out there!

Now a little preamble:

- In the last 4 years I developed 4 boards running iMX28 (imx280 and imx286) all running linux (3.12.1) running on top of a Debian Wheezy 7.8 armel distro.

Everything is working fine and our boards are using Ethernet, SDIO, LCD (where applicable), Touchscreen, Audio Output, CAN Bus, I2C, UART....) until now.

Last year we are asked to deploy a board with EARPHONE OUT, LINE IN/OUT and MIC IN all connected to the SGTL5000 as in IMX28EVK evaluation board.

Just to be clear: the OUTPUT (LineOUT or EarPhone) is WORKING GREAT!

In the bootlets code I am using the VCC_5WALL configuration as our board is running from power-outlet connector (i.e. no battery)

In the bootloader code (I am using Barebox 2013.02) I am configuring the GPIO 3.20, GPIO 3.21. GPIO 3.22, GPIO 3.23 and GPIO 3.24 as primary function i.e.: SAIF0_MCLK, SAIF0_LRCLK, SAIF0_BITCLK, SAIF0_SDATA0 and finally SAIF1_SDATA0.

When booting linux this board has a device-tree dts file with:

    apbx@80040000 {
   saif0: saif@80042000 {
   pinctrl-names = "default";
   pinctrl-0 = <&saif0_pins_a>;
   status = "okay";
   };

   saif1: saif@80046000 {
   pinctrl-names = "default";
   pinctrl-0 = <&saif1_pins_a>;
   fsl,saif-master = <&saif0>;
   status = "okay";
   };

and in the i2c section:

            i2c0: i2c@80058000 {

                pinctrl-names = "default";

                pinctrl-0 = <&i2c0_pins_a>;

                clock-frequency = <400000>;

                status = "okay";

                sgtl5000: codec@0a {

                    compatible = "fsl,sgtl5000";

                    reg = <0x0a>;

                    VDDA-supply = <&reg_3p3v>;

                    VDDIO-supply = <&reg_3p3v>;

                    clocks = <&saif0>;

                };

Because I am not using any VDDD i.e. it is left floating.

Finally in the latter section I have:

    sound {

        compatible = "fsl,imx28-evk-sgtl5000",

                 "fsl,mxs-audio-sgtl5000";

        model = "imx28-evk-sgtl5000";

        saif-controllers = <&saif0 &saif1>;

        audio-codec = <&sgtl5000>;

    };

With the same configuration in mind I rewrote the dts file for the IMX28EVK board too, and the bootlets code and bootloader Barebox are almost equal.

The Operating System (Debian Wheezy) is loaded from uSD Card in both systems and the kernel is the same, and the dtb file is loaded from bootloader, i.e. the bootloader knows about which board is running on, and select the device tree blob accordingly. When booting it select the correct dtb for the board itself... but the kernel and the OS are the same!

Well, when I type on IMX28EVK (iMX287):

arecord -t wav -d 5 -d hw:0,1 -f S16_LE -c 2 /tmp/sample.wav

the GPIO 3.26 (SAIF1_SDATA0) has a lot of data running, but after 5 seconds ( ... -d 5 above) it stops, it closes the file /tmp/sample.wav and returns no error.

Here is the configuration of the kernel drivers for audio:

Alsa Play APLAY version:

# aplay --version
aplay: version 1.0.25 by Jaroslav Kysela <perex@perex.cz>
# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: mxssgtl5000 [mxs_sgtl5000], device 0: HiFi Playback sgtl5000-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Alsa Record ARECORD version:

# arecord --version
arecord: version 1.0.25 by Jaroslav Kysela <perex@perex.cz>
# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: mxssgtl5000 [mxs_sgtl5000], device 1: HiFi Capture sgtl5000-1 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Here is the udev version:

# udevadm --version

175

When running the same command in the other board (with iMX286) I have 10 seconds of nothing, then this error:

reading from pcm (alsa arecord/aplay):

arecord: pcm_read:1801: read error: Input/output error
 From the source of 1.0.25 aplay/arecord:

1790           r = readi_func(handle, data, count);
1791           if (test_position)
1792                   do_test_position();
1793           if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) {
1794                   if (!test_nowait)
1795                           snd_pcm_wait(handle, 100);
1796           } else if (r == -EPIPE) {
1797                   xrun();
1798           } else if (r == -ESTRPIPE) {
1799                   suspend();
1800           } else if (r < 0) {
1801                   error(_("read error: %s"), snd_strerror(r));
1802                   prg_exit(EXIT_FAILURE);
1803           }
So the readi_func is failing. It seems there is a timeout or similar on
my board. On both boards (IMX28EVK and my board) I can clearly see
with a oscilloscope a signal on the SAIF1_SDATA0 (I2S_DOUT from
sgtl5000) during recording, so can I suppose the hardware configuration
of the pinmux is correct (on the .dts file)? I am using the same
pinout like on the EVK so no changes are needed to adapt to our board.
When arecord ends the SAIF1_SDATA0 line becomes high as normal.
When playing an audio file the line SAIF0_SDATA0 is oscillating during
all audio-playing-time as normal.
Playing with bootloader, I can clearly see all lines moving at my
command @ sgtl5000 pins, so I can exclude an defective soldering ball
between SoC and sgtl5000 itself.

Can I suppose NOT HAVING ANY HARDWARE ISSUE? Isn't it?

If someone is having/had a similar issue please feel free to contact me asap.

gianlucarenzi@eurek.it

Best Regards,

Labels (1)
0 Kudos
15 Replies

2,432 Views
gianlucarenzi71
Contributor II

Hello to everybody!

I had finally got a solution to this issue: the HW_DIGCTL_CTRL_SAIF_CLKMUX_SEL was not set.

On the cpu platform init code the register was updated only if the board model compatibility on the device-tree was set as: fsl,imx28-evk.

So my board had only those definitions in the .dts file:

compatible = "eurek,ek340", "fsl,imx28";

now it has also:

compatible = "eurek,ek340", "fsl,imx28-evk", "fsl,imx28";

just for enable the HW_DIGCTL_CTRL_SAIF_CLKMUX_SEL = MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 i.e. : 0x2

Thank you for your help.

Best Regards,

Gianluca Renzi@

0 Kudos

2,432 Views
lategoodbye
Senior Contributor I

Hi Gianluca,

thanks for providing your solution. But it isn't a proper one.

A proper solution for your problem will be to add board init function for "eurek,ek340" and call

mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);

just like eukrea_mbmx283lc_init() does.

Adding "fsl,imx28-evk" into your board dts would suggest that both are compatible and share the same Ethernet OUI.

Regards

Stefan

0 Kudos

2,432 Views
gianlucarenzi71
Contributor II

I know Stefan, but at this time I would avoid to patch the kernel source as little as possible. A single DTS change is less intrusive than modifying a Makefile and adding a baseboard support in the machine init code itself.

As soon those platforms are embedded into kernel, I will be happy to give them support to the up-to-date kernel! Right now I can load the 4.0.5 but the Wifi Module Support (BlueGiga WF111 CSR Based) is not compiling at all, the MMC core API has changed a little bit.

0 Kudos

2,432 Views
kerryknight
Contributor I

I had a similar problem with a custom iMX287 board, loosely based on the MX28EVK.  In my case it turned out to be no MIC_BIAS voltage was applied.  That can either be done from the device tree (depending on the Linux version used) or kludge the driver.  Mine now works perfectly, so might be worth a check.

0 Kudos

2,432 Views
gianlucarenzi71
Contributor II

Thank you Kerry for sharing your issues.

What do you mean with: no MIC_BIAS voltage was applied?

The MIC_BIAS line on the EVK are routed to a TEST POINT TP6, and in the device tree (3.12.1) I do not see anything about MIC_BIAS... I suppose you are referring to the programmable MIC_BIAS VOLTAGE Control (200mV less than VDDA?) Isn't it??  Are you referring of the

SGTL5000_CHIP_MIC_CTRL  

0x002a

as it is called in sgtl5000.h?? I suppose it is referred to any MIC IN as input source. But in my case it is not working MIC_IN neither in LINE_IN as in the MX28EVK does. Which is the correct way to set the CHIP_MIC_CTRL value to 7 (means 3.0 volts)?? I mean without changing the driver i.e. with alsa tools (mixer and such)?

Best regards,

Gianluca

0 Kudos

2,432 Views
kerryknight
Contributor I

I couldn't find a way to change the MIC_BIAS_VOLTAGE from any userspace tools, alsamixer etc., probably as the driver did not expose the bias stream.  I just added a default bias into the driver.

0 Kudos

2,432 Views
gianlucarenzi71
Contributor II

Can you explain better on how to add a default bias?

on Kernel 3.12.1 (sgtl5000.c) I can add:

snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, (0x7 << 4) | 2);

on the probe() function. Is it a viable solution? In our board (like IMX28EVK) the VDDA is running @ 3.3V so the CHIP_MIC_CTRL register (BIAS_VOLT) can be safely set @ 3.0V (0x7)...

Thank you for your patience...

0 Kudos

2,432 Views
kerryknight
Contributor I

I would check whether the mic bias voltage is not present with a voltmeter before much longer, just in case the problem is something totally unrelated to the MIC_BIAS_VOLTAGE, particularly as you say the same code build works with the EVK.  I suspect if it was missing microphone bias voltage, the EVK would have the same problem.

Good luck

0 Kudos

2,432 Views
gianlucarenzi71
Contributor II

Hello Kerry!

looking at the latest kernel 4.0.5 and in the kernel 3.19.8 like you are using, I have found a little issue about those device-tree variable you mentioned above:

in the function sgtl5000.c sgtl5000_probe (line 1341 in 4.0.5 and 1339 in 3.19.8) the lines:

snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
   SGTL5000_BIAS_R_MASK,
   sgtl5000->micbias_voltage << SGTL5000_BIAS_R_SHIFT);

must change to:

snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL,
   SGTL5000_BIAS_R_MASK,
   sgtl5000->micbias_voltage << SGTL5000_BIAS_VOLT_SHIFT);

Now I am wondering how you are finding the correct voltage in the MIC_BIAS pin... Are we talking about a side-effect of this BUG???

I will be glad if you are pointing me out on how to measure this voltage. In my board I was supposed to find 3000mV at the MIC_BIAS pin... ???

Anyway the board is not working either... :-(

0 Kudos

2,432 Views
gianlucarenzi71
Contributor II

a little typo:

snd_soc_update_bits(codec, SGTL5000_CHIP_MIC_CTRL, SGTL5000_BIAS_VOLT_MASK, sgtl5000->micbias_voltage << SGTL5000_BIAS_VOLT_SHIFT);

is the correct version.

Sorry! :-)

0 Kudos

2,432 Views
kerryknight
Contributor I

I used the device tree mechanism, although I'm on linux 3.19.8 and not sure when that was added.

                       i2c0: i2c@80058000 {

                               pinctrl-names = "default";

                               pinctrl-0 = <&i2c0_pins_a>;

                               status = "okay";

                               sgtl5000: codec@0a {

                                       compatible = "fsl,sgtl5000";

                                       reg = <0x0a>;

                                       clocks = <&saif0>;

                                        VDDA-supply = <&reg_3p3v>;

                                        VDDIO-supply = <&reg_3p3v>;

                                       micbias-resistor-k-ohms = <2>;

                                       micbias-voltage-m-volts = <2250>;

                               };

0 Kudos

2,432 Views
gianlucarenzi71
Contributor II

I just tried adding the:

{ SGTL5000_CHIP_MIC_CTRL,   0x0070 },

into the

/* default value of sgtl5000 registers */

static const struct reg_default sgtl5000_reg_defaults[] = {

and adding another:

snd_soc_write(codec, SGTL5000_CHIP_MIC_CTRL, (0x7 << 4) | 2);

in the function:

static int sgtl5000_probe(struct snd_soc_codec *codec)

and this modification is not help me out at all...

In the EVK the same is working as expected. :-(

0 Kudos

2,432 Views
gianlucarenzi71
Contributor II

Now I modified the mxs-saif.c and sgtl5000.c with a lot of debugging info, just to let me know if there is something which can be substantially different from IMX28EVK and EK340:

Here is the dmesg output for IMX28EVK recording 5 seconds of audio (I do not modify the INPUT SOURCE, so I suppose it is MIC_IN as amixer tells me that:)

Simple mixer control 'Capture Mux',0

  Capabilities: enum

  Items: 'MIC_IN' 'LINE_IN'

  Item0: 'MIC_IN'

---- DMESG OUTPUT:

mxs-saif 80046000.saif: mxs_saif_startup

sgtl5000 0-000a: sgtl5000_set_dai_sysclk Enter

mxs-saif 80046000.saif: mxs_saif_set_dai_sysclk CLKID: 0 FREQ: 11289600 DIR: 0

sgtl5000 0-000a: sgtl5000_set_dai_fmt Enter fmt: 16385

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

mxs-saif 80046000.saif: mxs_saif_set_dai_fmt fmt: 16385

sgtl5000 0-000a: sgtl5000_pcm_hw_params Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_set_clock Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

mxs-saif 80046000.saif: mxs_saif_hw_params

mxs-saif 80046000.saif: mclk 11289600 rate 22050

mxs-saif 80046000.saif: master saif0

mxs-saif 80046000.saif: mxs_saif_prepare

sgtl5000 0-000a: sgtl5000_set_bias_level Enter

sgtl5000 0-000a: power_vag_event event 1

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: power_vag_event event 2

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_set_bias_level Enter

mxs-saif 80046000.saif: mxs_saif_trigger

mxs-saif 80046000.saif: start

mxs-saif 80046000.saif: CTRL 0x2000807 STAT 0x80000040

mxs-saif 80042000.saif: CTRL 0x1 STAT 0x80010010

mxs-saif 80046000.saif: mxs_saif_irq

mxs-saif 80046000.saif: underrun!!! 1

mxs-saif 80046000.saif: SAIF_CTRL 2000807 SAIF_STAT 80000001

mxs-saif 80046000.saif: mxs_saif_trigger

mxs-saif 80046000.saif: stop

sgtl5000 0-000a: sgtl5000_set_bias_level Enter

sgtl5000 0-000a: power_vag_event event 4

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: power_vag_event event 8

sgtl5000 0-000a: sgtl5000_set_bias_level Enter

and now dmesg output of EK340 with the same command:

mxs-saif 80046000.saif: mxs_saif_startup

sgtl5000 0-000a: sgtl5000_set_dai_sysclk Enter

mxs-saif 80046000.saif: mxs_saif_set_dai_sysclk CLKID: 0 FREQ: 11289600 DIR: 0

sgtl5000 0-000a: sgtl5000_set_dai_fmt Enter fmt: 16385

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

mxs-saif 80046000.saif: mxs_saif_set_dai_fmt fmt: 16385

sgtl5000 0-000a: sgtl5000_pcm_hw_params Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_set_clock Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

mxs-saif 80046000.saif: mxs_saif_hw_params

mxs-saif 80046000.saif: mclk 11289600 rate 22050

mxs-saif 80046000.saif: master saif0

mxs-saif 80046000.saif: mxs_saif_prepare

sgtl5000 0-000a: sgtl5000_set_bias_level Enter

sgtl5000 0-000a: power_vag_event event 1

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: power_vag_event event 2

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_set_bias_level Enter

mxs-saif 80046000.saif: mxs_saif_trigger

mxs-saif 80046000.saif: start

mxs-saif 80046000.saif: CTRL 0x2000807 STAT 0x80000040

mxs-saif 80042000.saif: CTRL 0x1 STAT 0x80010010

mxs-saif 80046000.saif: mxs_saif_irq

mxs-saif 80046000.saif: underrun!!! 1

mxs-saif 80046000.saif: SAIF_CTRL 2000807 SAIF_STAT 80000000

mxs-saif 80046000.saif: mxs_saif_trigger

mxs-saif 80046000.saif: stop

sgtl5000 0-000a: sgtl5000_set_bias_level Enter

sgtl5000 0-000a: power_vag_event event 4

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: sgtl5000_readable Enter

sgtl5000 0-000a: sgtl5000_volatile Enter

sgtl5000 0-000a: power_vag_event event 8

sgtl5000 0-000a: sgtl5000_set_bias_level Enter

The only difference to me is the SAIF_STAT value into the mxs_saif_irq() function:

on IMX28EVK it is 80000001 that means BUSY, and in the EK340 it is 80000000 that is NOT BUSY.

What is it happening???? It looks like the SGTL5000 connected to the i.MX286 is not working for recording, meanwhile in the iMX287 is working as expected.

Some unknown hardware issue on the iMX286 side??

0 Kudos

2,432 Views
alejandrolozan1
NXP Employee
NXP Employee

Hi,

I would like to clarify if you are able to make it work in the imx28evk. As far as I understand it works in the EVK but not in your board right?

/Alejandro

0 Kudos

2,432 Views
gianlucarenzi71
Contributor II

Yes you are right.

It works on the IMX28EVK (i.MX287) and it DOES NOT work on our board. But the schematics are the same. If you want I can send the audio section to you just to see what's going on... but apart from the VDDA source (in the IMX28EVK it uses VDDIO_3V3 with a choke (L2) meanwhile in our board it uses an external VDDA_AUDIO from a voltage regulator driven from VDDIO_3V3...) they are IDENTICAL. LINE_IN_L/R are connected to a jack connector, MIC and MIC_BIAS in our board are connected to an external connector for microphone, LINE_OUT_L/R are routed to a jack connector and the HEADPHONE_L/R are routed to another jack connector.

I am so confused... I think all FAE from FSL will point me at using bootlets, u-boot and LTIB kernel and rootfs... and it is NOT A USABLE SOLUTION TO ME.

I think about dma/irq something related (kernel driver/pin misconfiguration/device-tree clash)... the (almost the) same software is working on EVK but not on our hardware.... :-(

0 Kudos