Capture I2S stream on imx6

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

Capture I2S stream on imx6

8,152 Views
jonashippold
NXP Employee
NXP Employee

Hi,

I have a device with I2S audio output that I want to capture using an i.mx6 board (Udoo).

On this board I can connect directly to the AUD5 pins of the i.mx6 quad.

Eventually, I want to have an ALSA/whatever device that is readable from userspace for capturing this audio stream.

What do I have to do to achieve that? I've read quite a lot, yet I'm more confused than before I started.

How do I set up the kernel? The pins are already configured correctly, but I don't know about the initialization code.

Is there already a driver that registers a device for me to read or do I need to code one myself?

Do I need any sort of audio codec for this? If I understand correctly, I'm simply capturing a digital data stream, so this should not need to much overhead.

So where do I go next?

Thanks in advance,

Jonas.

Labels (4)
Tags (4)
13 Replies

2,807 Views
delauratfrançoi
Contributor II

Hi Saurabh Patel

I have the same problem. We have bluetooth module (chip csr8811). The chip is connected with SAI bus. In our case we are not using any codec IC we want to capture raw PCM samples from SAI.

what the way foward?

That we must write in devicetree?

Must we creat a platform driver like Mohamed Thalib Haja?

Thanks,

François

0 Kudos

2,807 Views
YixingKong
Senior Contributor IV

Jonas

This discussion is closed since no activity. If you still need help, please feel free to reply with an update to this discussion, or create another discussion.

Thanks,

Yixing

0 Kudos

2,807 Views
mohamedthalibha
Contributor III

I am facing same issue, as stated in the above thread.

We have a bluetooth device connected to via I2S interface. Once the bluetooth interface is configured properly it will send PCM the data via I2S. we can see the bluetooth is sending the data using a oscilloscope

Now we want to record the data from IMX side, also do play back using arecord/aplay commands. Kindly let us know how we can do it. Which driver to use.

FYI: We are using Linux 3.10.17 running on IMX6 Solo.,

0 Kudos

2,807 Views
saurabh206
Senior Contributor III

Hi

Mohamed

You need to register platform driver for SSI configuration and you need to register dummy sound card.

Once your sound card registered correctly, you can use arecord/aplay command.

Thanks

Saurabh

0 Kudos

2,807 Views
mohamedthalibha
Contributor III

I have created a platform driver referred from sgtl and other drivers

Below is the source, is it correct. but I a getting timeout when using aplay, but no audio record interface is present. 

#include <linux/module.h>

#include <linux/of_platform.h>

#include <sound/soc.h>

#include <linux/of.h>

#include "imx-audmux.h"

struct imx_bt_data {

    struct snd_soc_dai_link dai;

    struct snd_soc_card card;

    struct platform_device *pdev;

};

static int imx_bt_audio_probe(struct platform_device *pdev)

{

    struct device_node *ssi_np, *np = pdev->dev.of_node;

    struct imx_bt_data *data;

    struct platform_device *ssi_pdev;

    int ret = 0, int_port, ext_port;

    /*

      Get the int and ext port from the dtb

    */

    ret = of_property_read_u32(np, "mux-int-port", &int_port);

    if (ret) {

        dev_err(&pdev->dev, "mux-int-port missing or invalid\n");

        return ret;

    }

    ret = of_property_read_u32(np, "mux-ext-port", &ext_port);

    if (ret) {

        dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");

        return ret;

    }

    /*

     * The port numbering in the hardware manual starts at 1, while

     * the audmux API expects it starts at 0.

     */

    int_port--;

    ext_port--;

    /*Configure the audmux*/

    ret = imx_audmux_v2_configure_port(int_port,

                       IMX_AUDMUX_V2_PTCR_SYN |

                       IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |

                       IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) |

                       IMX_AUDMUX_V2_PTCR_TFSDIR |

                       IMX_AUDMUX_V2_PTCR_TCLKDIR,

                       IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port));

    if (ret) {

        dev_err(&pdev->dev, "audmux internal port setup failed\n");

        return ret;

    }

    ret = imx_audmux_v2_configure_port(ext_port,

                       IMX_AUDMUX_V2_PTCR_SYN,

                       IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));

    if (ret) {

        dev_err(&pdev->dev, "audmux external port setup failed\n");

        return ret;

    }

    //Get the i2s controller from dtb

    ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);

    if (!ssi_np) {

        dev_err(&pdev->dev, "phandle missing or invalid\n");

        ret = -EINVAL;

        goto fail;

    }

   

    //find the i2s node and get its pdev struct

    ssi_pdev = of_find_device_by_node(ssi_np);

    if (!ssi_pdev) {

        dev_err(&pdev->dev, "failed to find SSI platform device\n");

        ret = -EINVAL;

        goto fail;

    }

    data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);

    if (!data) {

        dev_err(&pdev->dev, "failed to allocate memory\n");

        ret = -ENOMEM;

        goto fail;

    }

    data->dai.name = "ESOM BT HiFi";

    data->dai.stream_name = "Bluetooth Headphone";

    data->dai.codec_dai_name = "snd-soc-dummy-dai";

    data->dai.codec_name = "snd-soc-dummy";

    data->dai.cpu_of_node = ssi_np;

    data->dai.platform_of_node = ssi_np;

    data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |

        SND_SOC_DAIFMT_CBM_CFM;

    data->card.dev = &pdev->dev;

    data->card.num_links = 1;

    data->card.dai_link = &data->dai;

    data->pdev = platform_device_register_simple("bluetooth", -1, NULL, 0);

    if (IS_ERR(data->pdev)) {

        ret = PTR_ERR(data->pdev);

        dev_err(&pdev->dev, "register failed: %d\n", ret);

        goto fail;

    }

    //Fill in the card details

    ret = snd_soc_of_parse_card_name(&data->card, "model");

    if (ret)

        goto fail;

    data->card.num_links = 1;

    data->card.owner = THIS_MODULE;

    data->card.dai_link = &data->dai;

   

    platform_set_drvdata(pdev, &data->card);

    snd_soc_card_set_drvdata(&data->card, data);

    ret = snd_soc_register_card(&data->card);

    if (ret) {

        dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret);

        goto fail;

    }

    // Done, set the driver data.

    platform_set_drvdata(pdev, data);

   

fail:

    if (ssi_np)

        of_node_put(ssi_np);

    return ret;

}

static int imx_bt_audio_remove(struct platform_device *pdev)

{

    struct snd_soc_card *card = platform_get_drvdata(pdev);

    struct imx_bt_data *data = snd_soc_card_get_drvdata(card);

    snd_soc_unregister_card(card);

    platform_device_unregister(data->pdev);

    return 0;

}

static const struct of_device_id imx_bt_dt_ids[] = {

    { .compatible = "fsl,imx-audio-bt", },

    { }

};

MODULE_DEVICE_TABLE(of, imx_bt_dt_ids);

static struct platform_driver imx_bt_driver = {

    .driver = {

        .name = "imx-audio-bt",

        .owner = THIS_MODULE,

        .pm = &snd_soc_pm_ops,

        .of_match_table = imx_bt_dt_ids,

    },

    .probe = imx_bt_audio_probe,

    .remove = imx_bt_audio_remove,

};

module_platform_driver(imx_bt_driver);@

2,807 Views
mohamedthalibha
Contributor III
# insmod imx-esom-bt.ko 

imx-audio-esom-bt sound-bt.26:  snd-soc-dummy-dai <-> 202c000.ssi mapping ok

# cat /proc/asound/cards

0 [imx6qesomimx6sg]: imx6q-esomimx6- - imx6q-esomimx6-sgtl5000

                  imx6q-esomimx6-sgtl5000
1 [imxhdmisoc ]: imx-hdmi-soc - imx-hdmi-soc
                  imx-hdmi-soc
2 [imx6qesombt]: imx6q-esom-bt - imx6q-esom-bt
                  imx6q-esom-bt

# aplay -L

null

Discard all samples (playback) or generate zero samples (capture)

bluetooth

BT Headset

default:CARD=imx6qesomimx6sg

imx6q-esomimx6-sgtl5000,
Default Audio Device

sysdefault:CARD=imx6qesomimx6sg

imx6q-esomimx6-sgtl5000,
Default Audio Device

default:CARD=imxhdmisoc

imx-hdmi-soc,
Default Audio Device

sysdefault:CARD=imxhdmisoc

imx-hdmi-soc,
Default Audio Device

default:CARD=imx6qesombt

imx6q-esom-bt,
Default Audio Device

sysdefault:CARD=imx6qesombt

imx6q-esom-bt,
Default Audio Device

# aplay -Dhw:2,0 unmai.wav

Playing WAVE 'unmai.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

aplay: pcm_write:1939: write error: Input/output error

Device tree entires are below

+   sound-bt {
+           compatible = "fsl,imx-audio-esom-bt",
+                        "imx-audio-esom-bt";
+           model = "imx6q-esom-bt";
+           ssi-controller = <&ssi2>;
+           mux-int-port = <2>;
+           mux-ext-port = <5>;
+   };

Added below to audmux pin control

+                           MX6QDL_PAD_KEY_ROW1__AUD5_RXD  0x130b0
+                           MX6QDL_PAD_KEY_COL0__AUD5_TXC  0x130b0
+                           MX6QDL_PAD_KEY_ROW0__AUD5_TXD  0x110b0
+                           MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0

2,807 Views
saisuryanarayan
Contributor I

Hi Mohamed Thalib Haja,

Is your issue got resolved ?? We are also trying to capture PCM data over i2s using dummy driver what you have used.

0 Kudos

2,807 Views
saurabh206
Senior Contributor III

Hi

Saisurya

You can use "i.MX_6_BSP_Porting_Guide.pdf'

Chapter 8

Porting Audio Codecs to a Custom Board.

Thanks

Saurabh

0 Kudos

2,807 Views
saisuryanarayan
Contributor I

Hi Saurabh Patel,

Thankx for the reply.I have gone through the document.In our case we are not using any codec IC we want to capture raw PCM samples from SSI .

0 Kudos

2,807 Views
wriba
Contributor I

Hi Saisurya -

Did you have any success with this? I'm looking to send/receive PCM over SSI/AUDMUX without a codec IC.

0 Kudos

2,807 Views
YixingKong
Senior Contributor IV

Jonas

Had your issue got resolved? If yes, we are going to close the discussion in 3 days. If you still need help, please feel free to reply with an update to this discussion.

Thanks,

Yixing

0 Kudos

2,807 Views
XXiao1z
Contributor III

I'm doing something similar, to capture I2S_IN audio stream into iMX6 by trying to write an ALSA driver for the device that is sending out the audio stream via its I2S_OUT. This driver is quite different from those typical Alsa drivers such as stgl5000 etc.

0 Kudos

2,807 Views
jonashippold
NXP Employee
NXP Employee

Have you already achieved any progress in that project? Could you provide that driver code?

0 Kudos