1 2 Previous Next 18 Replies Latest reply on Mar 23, 2017 1:00 PM by Intel Corporation

    SSP2 port change from TDM 4 to TDM 8 channel question.

    bennnn

      Hi,

       

      I would like to change the dummy driver mode from PCM TDM 4 to 8 SLOTS.

       

      Do i need patch the Kernel in order to do this ? or do I just IO 4 or 8 channels to or from my device or ALSA ?

       

      audio guide explains we can look at the dummy driver here /linux/sound/soc/intel/board/merr_dpcm_dummy.c

       

      I have found this in upstream_to_edison.patch in the source  edison-src-ww18-15   ( code below )

       

      how do I change the dummy codec to PCM TDM  8 SLOTS ? is this possible ?

       

      or will I need to set the kernel command line to wm8958 and make my own machine driver with that?

       

      I don't need any machine control as I control my external DSP with I2C. I can set the DSP in slave mode on the 4 wires to SSP2.

       

      am i looking in the wrong place here?

       

       

      EDIT:  ok , I think I found the answer here External I2S wm8958 audio codec information

       

      static const struct sst_ssp_config

      sst_ssp_configs[SST_NUM_SSPS][SST_MAX_SSP_MUX][SST_MAX_SSP_DOMAINS] = {

      ...

              [SST_SSP2] = {

                      [SST_SSP_CODEC_MUX] = {

                              [SST_SSP_CODEC_DOMAIN] = {

                                      .ssp_id = SSP_CODEC,

                                      .bits_per_slot = 24,

                                      .slots = 4,

                                      .ssp_mode = SSP_MODE_MASTER,

                                      .pcm_mode = SSP_PCM_MODE_NETWORK,

                                      .duplex = SSP_DUPLEX,

                                      .ssp_protocol = SSP_MODE_PCM,

                                      .fs_width = 1,

                                      .fs_frequency = SSP_FS_48_KHZ,

                                      .active_slot_map = 0xF,

                                      .start_delay = 0,

                              },

                      },

              },

      };

       

       

      looks like i need to modify .slots = 4, to .slots = 8, and patch build a kernel with the modified patch.

       

      Is there an easier way to do this ? it seams like a long prcess !

       

       

       

       

       

       

      ASoc Dummy DPCM Machine driver for Intel Edison MID platform

      + *

      + *  Copyright (C) 2014 Intel Corp

      + *  Author: Michael Soares <michaelx.soares@intel.com>

      + *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      + *

      + *  This program is free software; you can redistribute it and/or modify

      + *  it under the terms of the GNU General Public License as published by

      + *  the Free Software Foundation; version 2 of the License.

      + *

      + *  This program is distributed in the hope that it will be useful, but

      + *  WITHOUT ANY WARRANTY; without even the implied warranty of

      + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

      + *  General Public License for more details.

      + *

      + *  You should have received a copy of the GNU General Public License along

      + *  with this program; if not, write to the Free Software Foundation, Inc.,

      + *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

      + *

      + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

      + */

      +

      +#include <linux/module.h>

      +#include <linux/init.h>

      +#include <linux/device.h>

      +#include <asm/intel_scu_pmic.h>

      +#include <asm/intel_sst_mrfld.h>

      +#include <sound/soc.h>

      +#include <sound/pcm_params.h>

      +

      +#ifdef CONFIG_PM_SLEEP

      +static int snd_merr_dpcm_prepare(struct device *dev)

      +{

      +    pr_debug("In %s device name\n", __func__);

      +    snd_soc_suspend(dev);

      +    return 0;

      +}

      +

      +static void snd_merr_dpcm_complete(struct device *dev)

      +{

      +    pr_debug("In %s\n", __func__);

      +    snd_soc_resume(dev);

      +    return;

      +}

      +

      +static int snd_merr_dpcm_poweroff(struct device *dev)

      +{

      +    pr_debug("In %s\n", __func__);

      +    snd_soc_poweroff(dev);

      +    return 0;

      +}

      +#else

      +#define snd_merr_dpcm_prepare NULL

      +#define snd_merr_dpcm_complete NULL

      +#define snd_merr_dpcm_poweroff NULL

      +#endif

      +

      +static unsigned int rates_48000[] = {

      +    48000,

      +};

      +

      +static struct snd_pcm_hw_constraint_list constraints_48000 = {

      +    .count = ARRAY_SIZE(rates_48000),

      +    .list  = rates_48000,

      +};

      +

      +static int merr_dummy_startup(struct snd_pcm_substream *substream)

      +{

      +    return snd_pcm_hw_constraint_list(substream->runtime, 0,

      +            SNDRV_PCM_HW_PARAM_RATE,

      +            &constraints_48000);

      +}

      +

      +static struct snd_soc_ops merr_dummy_ops = {

      +        .startup = merr_dummy_startup,

      +};

      +

      +static int merr_codec_fixup(struct snd_soc_pcm_runtime *rtd,

      +        struct snd_pcm_hw_params *params)

      +{

      +    struct snd_interval *rate = hw_param_interval(params,

      +            SNDRV_PCM_HW_PARAM_RATE);

      +    struct snd_interval *channels = hw_param_interval(params,

      +            SNDRV_PCM_HW_PARAM_CHANNELS);

      +

      +    pr_debug("Invoked %s for dailink %s\n", __func__, rtd->dai_link->name);

      +

      +    /* The DSP will convert the FE rate to 48k, stereo, 24bits */

      +    rate->min = rate->max = 48000;

      +    channels->min = channels->max = 2;

      +

      +    /* set SSP2 to 24-bit */

      +    snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -

      +                SNDRV_PCM_HW_PARAM_FIRST_MASK],

      +                SNDRV_PCM_FORMAT_S24_LE);

      +    return 0;

      +}

      +

      +struct snd_soc_dai_link merr_msic_dailink[] = {

      +    [MERR_DPCM_AUDIO] = {

      +        .name = "Media Audio Port",

      +        .stream_name = "Edison Audio",

      +        .cpu_dai_name = "Headset-cpu-dai",

      +        .codec_name = "snd-soc-dummy",

      +        .codec_dai_name = "snd-soc-dummy-dai",

      +        .platform_name = "sst-platform",

      +        .ignore_suspend = 1,

      +        .dynamic = 1,

      +        .ops = &merr_dummy_ops,

      +    },

      +    /* back ends */

      +    {

      +        .name = "SSP2-Codec",

      +        .be_id = 1,

      +        .cpu_dai_name = "ssp2-codec",

      +        .platform_name = "sst-platform",

      +        .no_pcm = 1,

      +        .codec_dai_name = "snd-soc-dummy-dai",

      +        .codec_name = "snd-soc-dummy",

      +        .be_hw_params_fixup = merr_codec_fixup,

      +        .ignore_suspend = 1,

      +    },

      +    {

      +        .name = "SSP1-BT",

      +        .be_id = 2,

      +        .cpu_dai_name = "snd-soc-dummy-dai",

      +        .platform_name = "snd-soc-dummy",

      +        .no_pcm = 1,

      +        .codec_name = "snd-soc-dummy",

      +        .codec_dai_name = "snd-soc-dummy-dai",

      +        .ignore_suspend = 1,

      +    },

      +

      +};

      +

      +static const struct snd_soc_dapm_route map[] = {

      +    { "Dummy Playback", NULL, "codec_out0"  },

      +    { "Dummy Playback", NULL, "codec_out1"  },

      +    { "codec_in0", NULL, "Dummy Capture" },

      +    { "codec_in1", NULL, "Dummy Capture" },

      +};

      +

      +/* SoC card */

      +static struct snd_soc_card snd_soc_card_merr = {

      +    .name = "dummy-audio",

      +    .dai_link = merr_msic_dailink,

      +    .num_links = ARRAY_SIZE(merr_msic_dailink),

      +    .dapm_routes = map,

      +    .num_dapm_routes = ARRAY_SIZE(map),

      +};

      +

      +static int snd_merr_dpcm_probe(struct platform_device *pdev)

      +{

      +    int ret_val = 0;

      +    pr_debug("%s enter\n", __func__);

      +

      +    /* register the soc card */

      +    snd_soc_card_merr.dev = &pdev->dev;

      +    ret_val = snd_soc_register_card(&snd_soc_card_merr);

      +    if (ret_val) {

      +        pr_err("snd_soc_register_card failed %d\n", ret_val);

      +        return ret_val;

      +    }

      +    platform_set_drvdata(pdev, &snd_soc_card_merr);

      +    pr_info("%s successful\n", __func__);

      +    return ret_val;

      +}

      +

      +static int snd_merr_dpcm_remove(struct platform_device *pdev)

      +{

      +    struct snd_soc_card *soc_card = platform_get_drvdata(pdev);

      +    pr_err("snd_merr_dpcm_remove");

      +    snd_soc_unregister_card(soc_card);

      +    platform_set_drvdata(pdev, NULL);

      +    return 0;

      +}

      +

      +const struct dev_pm_ops snd_merr_dpcm_mc_pm_ops = {

      +    .prepare = snd_merr_dpcm_prepare,

      +    .complete = snd_merr_dpcm_complete,

      +    .poweroff = snd_merr_dpcm_poweroff,

      +};

      +

      +static struct platform_driver snd_merr_dpcm_drv = {

      +    .driver = {

      +            .owner = THIS_MODULE,

      +            .name = "merr_dpcm_dummy",

      +            .pm = &snd_merr_dpcm_mc_pm_ops,

      +    },

      +    .probe = snd_merr_dpcm_probe,

      +    .remove = snd_merr_dpcm_remove,

      +};

      +

      +module_platform_driver(snd_merr_dpcm_drv);

      +

      +MODULE_DESCRIPTION("ASoC Intel(R) Edison dummy MID Machine driver");

      +MODULE_AUTHOR("Michael Soares <michaelx.soares@intel.com>");

      +MODULE_LICENSE("GPL v2");

      +MODULE_ALIAS("platform:merr_dpcm_dummy");

      +

      diff --git a/sound/soc/intel/board/merr_dpcm_wm8958.c b/sound/soc/intel/board/merr_dpcm_wm8958.c

      new file mode 100644

      index 0000000..3b89a82

      --- /dev/null

      +++ b/sound/soc/intel/board/merr_dpcm_wm8958.c

      @@ -0,0 +1,931 @@

        • 1. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
          Intel Corporation
          This message was posted on behalf of Intel Corporation

          Hello bennnn,

          Thanks for reaching out!

          First of all, I would like to say that I am glad to hear that you were able to find the answer to the original question.

          However, I'm afraid there is no other way than patching this setting on the kernel. I understand this might be a little bit challenging and could take a while, but I mean, good things are worth the wait.

          Please continue with your tests and keep us updated. We look forward to hearing from you. We would definitely appreciate if you could post the updates of your project in this thread, they might be of help for other users.
          -Peter.

          • 2. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
            bennnn

            OK,

             

            Does anyone know if its possible to have multiple dummy drivers in the kernel so we have multiple modes?

             

            I'm sure I can figure out how to patch the kernel for differnt modes one at a time , but multiple modes ? 48khz 96khz 16bit 24bit ?

             

            can I just name the dummy drivers dummy1 dummy2 and have ALSA route to / from them from YOCTO ? etc ?

             

            maybe just copy the code and rename the config for each mode ? or is there more config with ALSA to do that just that  ?

             

            Perhaps a very inificiant way to get differnt SSP2 modes but I am no kernel programer and have no idea how I could pass variables to the kernel

            dummy driver from my C++ code !!!

             

            Or, would it make more sence to inmpliment a machine driver ( hack the code dirver example ? )

             

            anyway , thanks for the Reply Peter

            • 3. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
              Intel Corporation
              This message was posted on behalf of Intel Corporation

              Hi bennnn,

              I'm not sure if it is possible to have multiple dummy drivers in the kernel in order to have multiple modes. I'd have to investigate if this can be achieved, I'll try to see what I can find out and if I'm able to get something useful I'll make sure to share it with you here.

              -Peter.

              • 4. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                bennnn

                can we load the dummy driver or machine driver with modprobe?

                maybe I could switch TDM / I2S etc modes that way ?

                 

                 

                 

                 

                 

                 

                • 5. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                  Intel Corporation
                  This message was posted on behalf of Intel Corporation

                  Hi bennnn,

                  We have been investigating on your questions, however, we would like to know what the final goal of your project is. If we know that, we might find another approach that could help us to achieve the goal.

                  Regarding you last post, we are not sure if switching modes that way is possible, but we are working on it. Please let us know your final goal, or if you have to follow some requirements for this project.

                  Hava a nice day!

                  Regards,
                  Diego

                  • 6. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                    bennnn

                    Hi Diego,

                     

                    I have made a DSP mixer board with 8 channel ADC and 8 channel DAC for audio mixing / recording / playback.

                     

                    I am looking for a way to record or playback multichannel audio from my board with 4 or 8 channel TDM. differnt number of channels / bitrates and sample rates. a multichannel digital audio recorder.

                     

                    I assume I can always send 8 channels from DSP even if I only record 1 channel with arecord in linux.

                    I would also like to change sample rates and or bitrates and have those options in my app. also start stop record & playback from file eventualy.

                     

                    I understand the default dummy driver is 4 channel TDM 24bit 48khz. I dont need machine control since I can controll the dsp adc and dac with i2c in c++ code with mraa i2c & gpo.

                     

                    I have an android bluetooth app for changing gain settings and various other DSP settings for mixing and mix routing of audio.

                    I have started to port that to edison form arduino IDE in eclipse C++ and would like to have this app change recording settings somehow on the edison.

                     

                    I have the arduino breakout but also now have the mini breakout which I would use with ssc /  i2c / spi / gpo 1.8v - 3.3v logic level shifters ( isolators )

                    assuming the SSC pins are also 1.8v logic.

                     

                    If I set the the dummy driver for instance to 8 slot TDM 96khz 24bit , but then get alsa ( arecord ) to record 4 channels of 48khz in 16bit I asume things will go wrong? or can ALSA down scale bitrate / sample rate in realtime ?

                     

                    thanks, Ben

                    • 7. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                      Intel Corporation
                      This message was posted on behalf of Intel Corporation

                      Great project! Thank you for the complete description.

                      I don't have much experience working on I2S so right now I don't have an specific suggestion for you, but let me investigate on it. The description of your project is really helpful to understand what you are trying to accomplish.

                      I'll try to get back to you as soon as possible.

                      Regards,
                      Diego

                      • 8. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                        Intel Corporation
                        This message was posted on behalf of Intel Corporation

                        Hello Ben,

                         

                        We have an update for your case.

                         

                        Unfortunately, we have confirmed that Edison cannot support >4 TDM slots at a bit-rate of 4 slots * 48kHz * 24bit. There are external devices that can add this functionality to the Edison, another option would be to use the Joule module. While the price point of the Joule module is considerably higher than the Edison, the Joule module offers better performance and processing power.

                         

                        We appreciate your patience and apologize for any inconvenience this might cause.
                        Pedro M.

                        • 9. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                          bennnn

                          Hi , from Intel® Edison Audio Setup Guide http://download.intel.com/support/edison/sb/edisonaudio_332434001.pdf

                           

                          SSP2 port tested configuration:

                          PCM TDM 4 slots

                          48 kHz

                          24 bits

                          Mono/dual mono/stereo

                           

                          I have the additional hardware and I'd like to switch configuration , 48khz , 96khz , 24bit , 16bit etc without rebooting into differnt custom kernels.

                           

                          Is there a misprint in the audio setup guide? I mean 4 audio channels on 1 x TDM bus over SSP2,

                          not 4 x TDM interfaces in case I descibed what i'm trying to do inccorectly.

                           

                          thanks , Ben

                          • 10. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                            Intel Corporation
                            This message was posted on behalf of Intel Corporation

                            Please let me check this. I will get back to you as quickly as possible.

                            Pedro M.

                            • 11. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                              naish

                              Hi Ben -

                              Your first statement is correct, "4 audio channels on 1 x TDM bus over SSP2".  There aren't 4 separate TDM interfaces - the interface, at least from a wiring standpoint are SSP ports, typically SSP ports can be configured for I2S, TDM, or PCM. Page 9 of the Edison Audio Setup Guide indicates what SSP1 and SSP2 support. On SSP2 with TDM, there is a maximum of 4 slots available. Hope this helps.

                              -tom

                              • 12. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                                bennnn

                                Hi Tom,

                                Thanks for looking into this. OK max 4 TDM audio channels.

                                 

                                So how to change the configuration of the SSP2 port ?

                                 

                                for instance SSP2 port config

                                 

                                from

                                4 channels TDM 24bit 48khz

                                 

                                to

                                4 channels TDM 16bit 96khz

                                 

                                how do you do this without rebuilding the dummy driver code in the kernel?

                                 

                                more than one instance of the dummy driver and load with modprobe ?

                                configure the SSP2 port for the highest bitrate and sample rate and throw lower audio bitrate / sample rate at the same config ?

                                • 13. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                                  Intel Corporation
                                  This message was posted on behalf of Intel Corporation

                                  Hi bennnn,

                                  We have an update for this case.

                                  You can switch bit and sampling rates, generally changed at runtime on Linux*, if the driver/codec support the changes. By default ALSA would pick the rates from the file being played, but that can be changed (e.g. using Pulseaudio as a layer on top of ALSA). A few examples include:
                                  http://unix.stackexchange.com/questions/74558/change-sampling-rate-in-alsa
                                  http://askubuntu.com/questions/138611/how-to-change-audio-bit-depth-and-sampling-rate. Please keep in mind that the maximum rate for Edison's audio is 48KHz.

                                  Please be aware that this is a software-based solution. But if a hardware-level solution is what you require, it would need deeper investigation, which would involve more time to look into it. 

                                  Pedro M.

                                  • 14. Re: SSP2 port change from TDM 4 to TDM 8 channel question.
                                    bennnn

                                    thanks Pedro,

                                     

                                    I'm going to try send differnt sample rates and see if ALSA will detect the changes

                                     

                                    Thanks for your reply,

                                     

                                    Ben

                                    1 2 Previous Next