[alsa-devel] Imx6 i2s master driver without i2c

Caleb Crome caleb at crome.org
Fri May 13 21:30:57 CEST 2016


On Fri, May 13, 2016 at 12:59 AM, nick83ola <nick83ola at gmail.com> wrote:

> Caleb thanks for your help!!!! the documentation is really orrible!!!!
>
> but now I'm getting something out of TXD!!!!
>

Wooo!


>
> only no clock and very fast (I think that I need to configure the
> oscillator/pll and iomux???)
>

Right, I wish I understood how to do that.  I don't.  It's got something to
do with some function called 'clock' I bet :-)  Or maybe 'clk'.  Or maybe
in the DTS and not a function call...


>
> In my kernel (3.14.28-1.0.0_ga+g91cf351) some of the statement in you dts
> are not supported in simple driver so I stripped down the imx-si476 driver
> and use with your dummy codec driver
>

Yeah, that's the problem with old kernels.  I try to just look towards the
future :-)

I'm glad things are working, and thanks for posting your working DTS.
Having your DTS here may help the next guy with an old kernel.

Cheers
-Caleb


>
> &audmux {
>     pinctrl-names = "default";
>     pinctrl-0 = <&pinctrl_audmux_4>;
>     status = "okay";
> };
>
> &ssi2 {
>     assigned-clocks = <&clks IMX6QDL_CLK_SSI2_SEL>;
>     assigned-clock-parents = <&clks IMX6QDL_CLK_PLL4_AUDIO_DIV>;
>     assigned-clock-rates = <0>;
>     fsl,mode = "i2s-master";
>     status = "okay";
> };
>
>
> / {
>     model = "Engicam i.CoreM6 DualLite/Solo starterkit";
>     compatible = "fsl,imx6-icore", "fsl,imx6dl";
>
>     codec_test: codec_test {
>         compatible = "linux,snd-soc-dummy";
>         status = "okay";
>     };
>
>     sound {
>         compatible = "fsl,imx-audio-itel";
>         model = "imx-itel";
>         ssi-controller = <&ssi2>;
>         audio-codec = <&codec_test>;
>         mux-int-port = <4>;
>         mux-ext-port = <2>;
>         status = "okay";
>     };
>
>     sound-hdmi {
>         status = "disabled";
>     };
> };
>
>
> &iomuxc {
>     audmux {
>         pinctrl_audmux_4: audmux-4 {
>             fsl,pins = <
>                 MX6QDL_PAD_DISP0_DAT20__AUD4_TXC  0x130b0
>                 MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x110b0
>                 MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS  0x130b0
>                 MX6QDL_PAD_DISP0_DAT23__AUD4_RXD  0x130b0
>             >;
>         };
>     };
> };
>
>
> ======================================================================================================================
> imx-itel.c
>
> ======================================================================================================================
>
>
> /*
>  * Copyright (C) 2013 Freescale Semiconductor, Inc.
>  *
>  * The code contained herein is licensed under the GNU General Public
>  * License. You may obtain a copy of the GNU General Public License
>  * Version 2 or later at the following locations:
>  *
>  * http://www.opensource.org/licenses/gpl-license.html
>  * http://www.gnu.org/copyleft/gpl.html
>  */
>
> #define DEBUG 1
>
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/of_platform.h>
> #include <linux/device.h>
> #include <linux/clk.h>
> #include <sound/core.h>
> #include <sound/pcm.h>
> #include <sound/soc.h>
> #include <sound/initval.h>
> #include <sound/pcm_params.h>
>
> #include "imx-audmux.h"
>
> struct imx_itel_data {
>     struct snd_soc_dai_link dai;
>     struct snd_soc_card card;
> };
>
>
> 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);
>
>     printk(KERN_ERR "--> ITEL imx-audmux-confic ext-port port=%#010x
> ptcr=%#010x pdcr=%#010x\n", master, ptcr, pdcr);
>
>     ptcr = IMX_AUDMUX_V2_PTCR_SYN;
>     pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(master);
>
>     printk(KERN_ERR "--> ITEL imx-audmux-config int-port port=%#010x
> ptcr=%#010x pdcr=%#010x\n", master, ptcr, pdcr);
>     imx_audmux_v2_configure_port(slave, ptcr, pdcr);
>
>     return 0;
> }
>
>
> static int imx_itel_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 = params_channels(params);
>     u32 rate = params_rate(params);
>     u32 bclk = rate * channels * 32;
>     int ret = 0;
>
>     printk(KERN_ERR "--> ITEL imx-itel-hw-params NAME=%s  \n VALUE=%#010x
> "
>                         "SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
> SND_SOC_DAIFMT_CBS_CFS\n",
>                         cpu_dai->name,
>                         (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
> SND_SOC_DAIFMT_CBS_CFS));
>
>     /* 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;
>     }
>     printk(KERN_ERR "--> ITEL imx-itel-hw-params set tdm slots
> channels=%d", channels);
>
>     ret = snd_soc_dai_set_tdm_slot(cpu_dai,
>             channels == 1 ? 0xfffffffe : 0xfffffffc,
>             channels == 1 ? 0xfffffffe : 0xfffffffc,
>             2, 32);
>     if (ret) {
>         dev_err(cpu_dai->dev, "failed to set dai tdm slot\n");
>         return ret;
>     }
>
>     printk(KERN_ERR "--> ITEL imx-audmux-config set sysclk NAME=%s
> \n",cpu_dai->name);
>
>     ret = snd_soc_dai_set_sysclk(cpu_dai, 0, bclk, SND_SOC_CLOCK_OUT);
>     if (ret)
>         dev_err(cpu_dai->dev, "failed to set sysclk\n");
>
>     return ret;
> }
>
>
> static struct snd_soc_ops imx_itel_ops = {
>     .hw_params = imx_itel_hw_params,
> };
>
>
> static struct snd_soc_dai_link imx_itel_dai[] = {
>     {
>         .name            = "Hifi",
>         .stream_name     = "Hifi",
>         .codec_dai_name     = "snd-soc-dummy-dai",
>         //.codec_name         = "snd-soc-dummy",
>         .ops             = &imx_itel_ops,
>         // .symmetric_rates = 1,
>     },
> };
>
> static struct snd_soc_card snd_soc_card_imx_itel = {
>     .name       = "imx-audio-itel",
>     .dai_link   = imx_itel_dai,
>     .num_links    = ARRAY_SIZE(imx_itel_dai),
>     .owner      = THIS_MODULE,
> };
>
>
> static int imx_itel_probe(struct platform_device *pdev)
> {
>     struct snd_soc_card *card = &snd_soc_card_imx_itel;
>     struct device_node *ssi_np;
>     struct platform_device *ssi_pdev;
>     struct device_node *codec_np;
>     // struct imx_itel_data *data = NULL;
>     int int_port, ext_port, ret;
>
>     printk(KERN_ERR "--> ITEL imx_itel_probe");
>
>     ret = of_property_read_u32(pdev->dev.of_node, "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(pdev->dev.of_node, "mux-ext-port",
> &ext_port);
>     if (ret) {
>         dev_err(&pdev->dev, "mux-ext-port missing or invalid\n");
>         return ret;
>     }
>
>     printk(KERN_ERR "--> ITEL Configuro audmux\n");
>     imx_audmux_config(int_port, ext_port);
>
>     /* find value in devicetree for ssi controller */
>     ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0);
>     if (!ssi_np) {
>         dev_err(&pdev->dev, "ssi-controller missing or invalid\n");
>         ret = -EINVAL;
>         goto fail;
>     }
>
>     /* find SSI platform driver */
>     ssi_pdev = of_find_device_by_node(ssi_np);
>     if (!ssi_pdev) {
>         dev_err(&pdev->dev, "failed to find SSI platform device\n");
>         ret = -EPROBE_DEFER;
>         goto fail;
>     }
>
>     codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0);
>     if (!codec_np) {
>         dev_err(&pdev->dev, "codec missing or invalid\n");
>         ret = -EINVAL;
>         goto fail;
>     }
>
>     // codec_dev = NULL;
>
>     card->dev = &pdev->dev;
>     card->dai_link->cpu_dai_name = dev_name(&ssi_pdev->dev);
>     card->dai_link->platform_of_node = ssi_np;
>     card->dai_link->codec_of_node = codec_np;
>
>     platform_set_drvdata(pdev, card);
>     snd_soc_card_set_drvdata(card, &snd_soc_card_imx_itel);
>
>     printk(KERN_ERR "--> ITEL imx-probe registro card\n");
>
>     ret = snd_soc_register_card(card);
>     if (ret) {
>         dev_err(&pdev->dev, "Failed to register card: %d\n", ret);
>         goto fail;
>     }
>
>     printk(KERN_ERR "--> ITEL imx-probe of ssi\n");
>     of_node_put(ssi_np);
>     printk(KERN_ERR "--> ITEL imx-probe of codec\n");
>     of_node_put(codec_np);
>
>     return 0;
>
> fail:
>     if (ssi_np)
>         of_node_put(ssi_np);
>     if (codec_np)
>         of_node_put(codec_np);
>
>     return ret;
> }
>
> static int imx_itel_remove(struct platform_device *pdev)
> {
>     struct snd_soc_card *card = &snd_soc_card_imx_itel;
>
>     snd_soc_unregister_card(card);
>
>     return 0;
> }
>
> static const struct of_device_id imx_itel_dt_ids[] = {
>     { .compatible = "fsl,imx-audio-itel", },
>     { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, imx_itel_dt_ids);
>
> static struct platform_driver imx_itel_driver = {
>     .driver = {
>         .name = "imx-itel",
>         .owner = THIS_MODULE,
>         .pm = &snd_soc_pm_ops,
>         .of_match_table = imx_itel_dt_ids,
>     },
>     .probe = imx_itel_probe,
>     .remove = imx_itel_remove,
> };
>
> module_platform_driver(imx_itel_driver);
>
> MODULE_AUTHOR("Nicola Lunghi");
> MODULE_DESCRIPTION("ITEL I2S Platform Driver");
> MODULE_LICENSE("GPL v2");
> MODULE_ALIAS("platform:imx-itel");
>
> 2016-05-12 9:55 GMT+02:00 nick83ola <nick83ola at gmail.com>:
>
>> I am using ssi1 because I have an example of setting master mode on sabre
>> board dts
>>
>> I have a problem with iomux/pinctrl  I think because
>>
>> root at icorem6solo:/sys/kernel/debug/pinctrl/20e0000.iomuxc# cat
>> pinmux-pins |grep audmux
>> pin 57 (MX6DL_PAD_DISP0_DAT20): 2028000.ssi (GPIO UNCLAIMED) function
>> audmux group audmux-4
>> pin 58 (MX6DL_PAD_DISP0_DAT21): 2028000.ssi (GPIO UNCLAIMED) function
>> audmux group audmux-4
>> pin 59 (MX6DL_PAD_DISP0_DAT22): 2028000.ssi (GPIO UNCLAIMED) function
>> audmux group audmux-4
>> pin 60 (MX6DL_PAD_DISP0_DAT23): 2028000.ssi (GPIO UNCLAIMED) function
>> audmux group audmux-4
>>
>> says: GPIO_UNCLAIMED? it is correct??
>>
>> /sys/kernel/debug/pinctrl/20e0000.iomuxc# cat pinconf-groups |grep -A 1
>> audmux
>> 1 (audmux-1):
>> MX6DL_PAD_SD2_DAT0: 0x17070MX6DL_PAD_SD2_DAT3: 0x17070MX6DL_PAD_SD2_DAT2:
>> 0x17070MX6DL_PAD_SD2_DAT1: 0x17070
>> 2 (audmux-2):
>> MX6DL_PAD_CSI0_DAT7: 0x1b0b0MX6DL_PAD_CSI0_DAT4:
>> 0x1b0b0MX6DL_PAD_CSI0_DAT5: 0x1b0b0MX6DL_PAD_CSI0_DAT6: 0x1b0b0
>> 3 (audmux-3):
>> MX6DL_PAD_DISP0_DAT16: 0x10MX6DL_PAD_DISP0_DAT18:
>> 0x1b0b0MX6DL_PAD_DISP0_DAT19: 0x1b0b0
>> 4 (audmux-4):
>> MX6DL_PAD_DISP0_DAT20: 0x130b0MX6DL_PAD_DISP0_DAT21:
>> 0x110b0MX6DL_PAD_DISP0_DAT22: 0x130b0MX6DL_PAD_DISP0_DAT23: 0x130b0
>>
>> 0x130b0?
>>
>> audmux# cat ssi0
>>     PDCR: 0000a000
>>     PTCR: ad400800
>>     TxFS output from SSI6, TxClk output from SSI6
>>     Port is symmetric
>>     Data received from SSI6
>> root at icorem6solo:/sys/kernel/debug/audmux# cat ssi1
>>     PDCR: 00008000
>>     PTCR: 00000800
>>     TxFS input, TxClk input
>>     Port is symmetric
>>     Data received from SSI5
>> root at icorem6solo:/sys/kernel/debug/audmux# cat ssi2
>>     PDCR: 00006000
>>     PTCR: 9cc00800
>>     TxFS output from SSI4, TxClk output from SSI4
>>     Port is symmetric
>>     Data received from SSI4
>> root at icorem6solo:/sys/kernel/debug/audmux# cat ssi3
>>     PDCR: 00004000
>>     PTCR: 00000800
>>     TxFS input, TxClk input
>>     Port is symmetric
>>     Data received from SSI3
>> root at icorem6solo:/sys/kernel/debug/audmux# cat ssi4
>>     PDCR: 00002000
>>     PTCR: 8c400800
>>     TxFS output from imx-ssi.1, TxClk output from imx-ssi.1
>>     Port is symmetric
>>     Data received from imx-ssi.1
>> root at icorem6solo:/sys/kernel/debug/audmux# cat ssi5
>>     PDCR: 00000000
>>     PTCR: 00000800
>>     TxFS input, TxClk input
>>     Port is symmetric
>>     Data received from imx-ssi.0
>> root at icorem6solo:/sys/kernel/debug/audmux# cat ssi6
>>     PDCR: 0000c000
>>     PTCR: 00000800
>>     TxFS input, TxClk input
>>     Port is symmetric
>>     Data received from UNKNOWN
>>
>>
>>
>
>
> --
>
> P.S. Le informazioni trasmesse attraverso la presente comunicazione sono
> di esclusiva
> spettanza dell'effettivo destinatario. Nel caso in cui le stesse
> raggiungessero, per
> qualunque motivo, soggetti non interessati, questi ultimi vorranno darne
> immediata
> notizia al mittente. In ogni caso, eventuali soggetti diversi dai
> legittimi destinatari
> della presente comunicazione e dei dati contenuti negli allegati, possono
> essere
> sanzionati ai sensi del T.U. sul trattamento dei dati personali d.lgs.
> 196/2003, sia ai
> sensi dell'art. 616 del Codice Penale che disciplina la violazione del
> segreto sulla
> corrispondenza.
>


More information about the Alsa-devel mailing list