This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Porting new codec for am335x

Other Parts Discussed in Thread: TLV320AIC3106, TEST2, PCM5102A

Dear TI E2E Community,

I am working in porting of new stereo codec , I followed the links
http://processors.wiki.ti.com/index.php/Sitara_SDK_Linux_Audio_Porting_Guide
http://processors.wiki.ti.com/index.php/Sitara_Linux_SDK_Audio_DAC_Example

As I am new to dts configuration &  not clear w.r.t the following points could anybody please clarify on the same

1) I did the pins muxing as shown below, could you anybody please confirm whether the SYSCLK needs to be configured here (ie., in this pin muxing only) or it is not required configured here or somehwere else??

        mcasp0_pins: mcasp0_pins {
                        pinctrl-single,pins = <
                                0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp0_ahclkx - SYSCLK */
                                0x190 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp0_aclkx - BCK   */
                                0x194 (PIN_INPUT_PULLDOWN| MUX_MODE0)     /* mcasp0_fsx -  WS     */
                                0x198 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr0 - DATAO  */
                0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE0)  /* mcasp0_axr1 - DATAI  */
            
                        >;
                };
 
                mcasp0_sleep_pins: mcasp0_sleep_pins {
                        pinctrl-single,pins = <
                                0x1ac (PIN_INPUT_PULLDOWN | MUX_MODE7)
                                0x190 (PIN_INPUT_PULLDOWN | MUX_MODE7)
                                0x194 (PIN_INPUT_PULLDOWN | MUX_MODE7)
                                0x198 (PIN_INPUT_PULLDOWN | MUX_MODE7)
                0x1a8 (PIN_INPUT_PULLDOWN | MUX_MODE7)
                        >;
                };


2) In machine layer configuration , I didn't understand what is codec-clock-rate?? is this the master clock or bit clock of stereo codec,
If it is master clock, could you please clarify is 12Mhz is sufficient for codec to respond, since I require my stereo codec to work at 12 bit @ 48 KHz & With respect to audio routing as am using UDA1345TS chipset & I see the below routing configurations  in the codec driver file which is already in place (sound/soc/codecs/uda134x.c)

static const struct snd_soc_dapm_widget uda134x_dapm_widgets[] = {
    SND_SOC_DAPM_INPUT("VINL1"),
    SND_SOC_DAPM_INPUT("VINR1"),
    //SND_SOC_DAPM_INPUT("VINL2"),
    //SND_SOC_DAPM_INPUT("VINR2"),
    SND_SOC_DAPM_OUTPUT("VOUTL"),
    SND_SOC_DAPM_OUTPUT("VOUTR"),
};

static const struct snd_soc_dapm_route uda134x_dapm_routes[] = {
    { "ADC", NULL, "VINL1" },
    { "ADC", NULL, "VINR1" },
    //{ "ADC", NULL, "VINL2" },
    //{ "ADC", NULL, "VINR2" },
    { "VOUTL", NULL, "DAC" },
    { "VOUTR", NULL, "DAC" },
};

I have added the same configurations in dts as shown below ,could you please confirm the below configurations w.r.t audio routing is correct or any other configurations needs to be done apart from this

    uda134x: uda134x {
        compatible = "ti,uda134x";
    };
 
        sound {
                        compatible = "ti,uda134x-audio-codec";
                        ti,model = "AM335x-EVM";
                        ti,audio-codecaudio-codec = <&uda134x>;
                        ti,mcasp-controller = <&mcasp0>;
                        ti,codec-clock-rate = <12000000>;
                        ti,audio-routing =
                                "ADC",         "VINL1",
                                "ADC",         "VINR1";
                                "VOUTL",       "DAC",
                                "VOUTR",       "DAC",
 
         };

3) In MCASP configuration as shown below I didn't understand the following parameters, could anybody please explain the same, so that it
taken care for porting my new audio codec

I feel important parameter is serial-dir , could you please help me to understand what is serial-dir  & other parameters also
tdm-slots
tx-num-evt
rx-num-evt  

&mcasp0 {
                pinctrl-names = "default", "sleep";
                pinctrl-0 = <&mcasp0_pins>;
                pinctrl-1 = <&mcasp0_sleep_pins>;
 
                status = "okay";
 
                op-mode = <0>;          /* MCASP_IIS_MODE */
                tdm-slots = <2>;
                /* 16 serializer */
                serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
                        0 0 1 2
                >;
                tx-num-evt = <32>;
                rx-num-evt = <32>;
};

Kindly do the needful in clarifying the above queries as early as possible, so that I can quickly bringup the codec up & running with better understanding

Awaiting for your replies

Many Many Thanks in advance.

  • Hi Srini,


    Here is what I can answer of your questions:


    1. Yes, you should set the clk pad in this device tree node.

    2. codec-clock-rate is the master clock outputted from the host processor to the codec. For your application 2channels x 12bits @ 48KHz the 12MHz clock is sufficient.

    3. 

     3.1 tx-num-evt & rx-num-evt

    Those are event pacer for the Audio FIFOs (Write FIFO & Read FIFO), that is a configurable threshold that reduces the number of DMA transactions. The event pacer is helpful to reduce the effect of bus latency for high sample frequencies or long frames.

    AFIFO is configured through the following two DT parameters:

       tx-num-evt - this is a write fifo threshold. Number of samples between 1 and 64

       rx-num-evt - this is a write fifo threshold. Number of samples between 1 and 64

      3.2 tdm-slots: this parameter just points the number of TDM slots.

      3.3 The serial-dir is an array describing the serializer direction.  0: means serializer is inactive, 1: means serializer is used for transmit, 2: means serializer is used for receive.

        For example if you need all 4 serializers (AXR0, AXR1, AXR2, AXR3) for mcasp0 of which AXR1 is transmit, AXR2 is receive, AXR3 & AXR4 are inactive you need to configure as follows:
       mcasp0 {
                       ..................

                       num-serializer = <4>;

                       serial-dir = <1 2 0 0>;

                      ...................

    };

    In your case:
                   

    Srini S said:
    serial-dir = <  /* 0: INACTIVE, 1: TX, 2: RX */
                            0 0 1 2
                    >;

    This configuration means that AXR0 & AXR1 are not used (INACTIVE) AXR2 is TX, and AXR is RX.

    Hope this helps.

    Best Regards,
    Yordan
        

  • Many Thanks a lot for your quick replies Yordan, it is really helpful for me in progressing further with enough confidence,
    If possible could you please clarify my point w.r.t audio routing mentioned above, as this the only doubt I have for my porting activity

    Kindly do the needful as early as possible

    Many Thanks again for your quick replies

  • Hi Srini,

    Sorry, I've missed that. The audio-routing configuration also seems correct.

    Best Regards,
    Yordan
  • Many Thanks a lot & appreciate Yordan for your quick support, & am able to progress further with these inputs from you..
  • Hi Yordan,

    I am using UDA1345TS audio codec in my custom board which is based on beaglebone black for am335x platform and am using ti-sdk-am335x-evm-07.00.00.00 BSP, as am new to this DTS as previously worked on board file

    so I found the UDA134x audio codec driver as the reference which was used for s3c24xx platform (based on board file) & the relevant driver files are as shown below

    arch/arm/mach-s3c24xx/Mach-mini2440.c
    sound/soc/samsung/s3c24xx_uda134x.c
    sound/soc/codecs/L3.c

    So I wanted to port the same onto ti-sdk-am335x-evm-07.00.00.00 BSP's which is based on dts & not board file,

    As am new to this DTS as previously worked on board file & even most of the porting related to audio codec is done on the following files w.r.t L3 bus

    In sound/soc/davinci/Davinci-evm.c similar to s3c24xx_uda134x.c
    ============================================================

    struct am335x_uda134x_platform_data {
        int l3_clk;
        int l3_mode;
        int l3_data;
        void (*power) (int);
        int model;
    };

    static struct am335x_uda134x_platform_data *am335x_uda134x_l3_pins;

    #if IS_ENABLED(CONFIG_OF)
    static int davinci_uda1345_probe_dt(/*struct am335x_uda134x_platform_data *data,*/
                 struct platform_device *pdev)
    {
        
        struct device_node *node = pdev->dev.of_node;
        struct am335x_uda134x_platform_data *pdata;
        enum of_gpio_flags ofgpioflags;
           int ret, gpio;
        

        if (!node)
            return -EINVAL;


         pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
            if (pdata == NULL)
                        return NULL; /* out of memory */


                        /* now get the power gpio and set it to one */
                    gpio = of_get_named_gpio_flags(pdev->dev.of_node, "power-gpio",
                                    0, &ofgpioflags);
                    if (!IS_ERR_VALUE(gpio)) {
                            gpioflags = GPIOF_DIR_OUT;
                            if (ofgpioflags & OF_GPIO_ACTIVE_LOW)
                                    gpioflags |= GPIOF_INIT_LOW;
                            else
                                    gpioflags |= GPIOF_INIT_HIGH;
                            ret = devm_gpio_request_one(&pdev->dev, gpio,
                                            gpioflags, "foo-power");
                    }

                    /* pdata->bar is filled in with 5 */

                         /* no such property */
            if (of_property_read_u32(node, "l3_clk", &pdata->l3_clk) != 0)
                        return NULL;

         if (of_property_read_u32(node, "l3_mode", &pdata->l3_mode) != 0)
                        return NULL;

          if (of_property_read_u32(node, "l3_data", &pdata->l3_data) != 0)
                        return NULL;
             
                    /* pdata->bar is filled in with 5 */
             return pdata;
        
       
    }
    #endif

    static int davinci_evm_probe(struct platform_device *pdev)
    {
        struct device_node *np = pdev->dev.of_node;
        const struct of_device_id *match =
            of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
        struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data;
        struct snd_soc_card_drvdata_davinci *drvdata = NULL;
        struct clk *mclk;
        int ret = 0;

        evm_soc_card.dai_link = dai;

    #if 1
        printk(KERN_INFO "AM335XXXXXXXXXXXXXXXXXXX_UDA134X SoC Audio driver\n");

        am335x_uda134x_l3_pins = pdev->dev.platform_data;
        if (am335x_uda134x_l3_pins == NULL) {
            printk(KERN_ERR "AM335X_UDA134X SoC Audio: "
                   "unable to find platform data\n");
            return -ENODEV;
        }
        am335x_uda134x.power = am335x_uda134x_l3_pins->power;
        am335x_uda134x.model = am335x_uda134x_l3_pins->model;

        if (am335x_uda134x_setup_pin(am335x_uda134x_l3_pins->l3_data,
                          "data") < 0)
            return -EBUSY;
        if (am335x_uda134x_setup_pin(am335x_uda134x_l3_pins->l3_clk,
                          "clk") < 0) {
            gpio_free(am335x_uda134x_l3_pins->l3_data);
            return -EBUSY;
        }
        if (am335x_uda134x_setup_pin(am335x_uda134x_l3_pins->l3_mode,
                          "mode") < 0) {
            gpio_free(am335x_uda134x_l3_pins->l3_data);
            gpio_free(am335x_uda134x_l3_pins->l3_clk);
            return -EBUSY;
        }

    #endif

        dai->codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0);
        if (!dai->codec_of_node)
            return -EINVAL;

        dai->cpu_of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
        if (!dai->cpu_of_node)
            return -EINVAL;

        /* Only set the platform_of_node if the platform_name is not set */
        if (!dai->platform_name)
            dai->platform_of_node = dai->cpu_of_node;

        evm_soc_card.dev = &pdev->dev;
        ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model");
        if (ret)
            return ret;

        mclk = of_clk_get_by_name(np, "ti,codec-clock");
        if (PTR_ERR(mclk) == -EPROBE_DEFER)
            return -EPROBE_DEFER;
        else if (IS_ERR(mclk)) {
            dev_dbg(&pdev->dev, "Codec clock not found.\n");
            mclk = NULL;
        }

        drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
        if (!drvdata)
            return -ENOMEM;

        drvdata->mclk = mclk;

        ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk);

        if (ret < 0) {
            if (!drvdata->mclk) {
                dev_err(&pdev->dev,
                    "No clock or clock rate defined.\n");
                return -EINVAL;
            }
            drvdata->sysclk = clk_get_rate(drvdata->mclk);
        } else if (drvdata->mclk) {
            unsigned int requestd_rate = drvdata->sysclk;
            clk_set_rate(drvdata->mclk, drvdata->sysclk);
            drvdata->sysclk = clk_get_rate(drvdata->mclk);
            if (drvdata->sysclk != requestd_rate)
                dev_warn(&pdev->dev,
                     "Could not get requested rate %u using %u.\n",
                     requestd_rate, drvdata->sysclk);
        }

        snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
        ret = snd_soc_register_card(&evm_soc_card);

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

        return ret;
    }

    arch/arm/boot/dts/am335x-bone-common.dtsi similar to Mach-mini2440.c
    ====================================================================
     
            uda1345_l3_default: uda1345_l3_default {
                pinctrl-single,pins = <
                    0xc8 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpio2_16.LCD_DATA10.U3 MP1 OVERFL output */
                    0xcc (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpio2_17.LCD_DATA11.U4 MP2 L3MODE  */
                    0xd8 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpio0_10.LCD_DATA14.V4 MP3 L3CLOCK */
                    0xd0 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpio0_8.LCD_DATA12.V2 MP4 L3DATA   */
                    0xd4 (PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpio0_9.LCD_DATA13.V3 MP5 ADC 1V or 2V (RMS) input control*/
                >;
            };
     
            uda1345_l3_sleep: uda1345_l3_sleep {
                pinctrl-single,pins = <

                    0xc8 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpio2_16.LCD_DATA10.U3 MP1 OVERFL output */
                    0xcc (PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpio2_17.LCD_DATA11.U4 MP2 L3MODE  */
                    0xd8 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpio0_10.LCD_DATA14.V4 MP3 L3CLOCK */
                    0xd0 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpio0_8.LCD_DATA12.V2 MP4 L3DATA   */
                    0xd4 (PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpio0_9.LCD_DATA13.V3 MP5  ADC 1V or 2V (RMS) input control*/
            
     
                >;
            };
     
         uda1345_l3 {
            pinctrl-names = "default", "sleep";
            pinctrl-0 = <&uda1345_l3_default>;
            pinctrl-1 = <&uda1345_l3_sleep>;
     
            compatible = "uda1345_l3";

        };

    sound/soc/codecs/uda134x.c
    ===========================

    #if defined(CONFIG_OF)
    static const struct of_device_id uda134x_dt_ids[] = {
        { .compatible = "ti,uda134x" },
        { }
    };
    MODULE_DEVICE_TABLE(of, uda134x_dt_ids);
    #endif


    static struct platform_driver uda134x_codec_driver = {
        .driver = {
            .name = "uda134x-codec",
            .owner = THIS_MODULE,
            .of_match_table = of_match_ptr(uda134x_dt_ids),
        },
        .probe = uda134x_codec_probe,
        .remove = uda134x_codec_remove,
    };

    Except L3 bus driver, the below shows this is the platform data (based on board file Mach-mini2440.c & s3c24xx_uda134x.c), could you please kindly do the needful & help me in porting L3 driver on DTS & I have ported few L3 lines in Davinci-evm.c & am335x-bone-common.dtsi as shown above  (which is in the above attachment by googling few links like  &Device Tree for Dummies - Free Electrons ) but this did not work & am struggling from many days still am not able to succeed with this L3 bus driver based on DTS

    arch/arm/mach-s3c24xx\Mach-mini2440.c
    =======================================

    /* AUDIO */

    static struct s3c24xx_uda134x_platform_data mini2440_audio_pins = {

       .l3_clk = S3C2410_GPB(4),

       .l3_mode = S3C2410_GPB(2),

       .l3_data = S3C2410_GPB(3),

       .model = UDA134X_UDA1341

    };

    static struct platform_device mini2440_audio = {

       .name        = "s3c24xx_uda134x",

       .id        = 0,

       .dev        = {

           .platform_data    = &mini2440_audio_pins,

       },

    };

    sound/soc/samsung/s3c24xx_uda134x.c
    =======================================

    static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;

    static void setdat(int v)

    {

       gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);

    }

    static void setclk(int v)

    {

       gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);

    }

    static void setmode(int v)

    {

       gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);

    }

    /* FIXME - This must be codec platform data but in which board file ?? */

    static struct uda134x_platform_data s3c24xx_uda134x = {

       .l3 = {

           .setdat = setdat,

           .setclk = setclk,

           .setmode = setmode,

           .data_hold = 1,

           .data_setup = 1,

           .clock_high = 1,

           .mode_hold = 1,

           .mode = 1,

           .mode_setup = 1,

       },

    };

    static int s3c24xx_uda134x_setup_pin(int pin, char *fun)

    {

       if (gpio_request(pin, "s3c24xx_uda134x") < 0) {

           printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "

                  "l3 %s pin already in use", fun);

           return -EBUSY;

       }

       gpio_direction_output(pin, 0);

       return 0;

    }

    static int s3c24xx_uda134x_probe(struct platform_device *pdev)

    {

       int ret;

       printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");

       s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;

       if (s3c24xx_uda134x_l3_pins == NULL) {

           printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "

                  "unable to find platform data\n");

           return -ENODEV;

       }

       s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;

       s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;

       if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,

                         "data") < 0)

           return -EBUSY;

       if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,

                         "clk") < 0) {

           gpio_free(s3c24xx_uda134x_l3_pins->l3_data);

           return -EBUSY;

       }

       if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,

                         "mode") < 0) {

           gpio_free(s3c24xx_uda134x_l3_pins->l3_data);

           gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);

           return -EBUSY;

       }

       s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);

       if (!s3c24xx_uda134x_snd_device) {

           printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "

                  "Unable to register\n");

           return -ENOMEM;

       }

       platform_set_drvdata(s3c24xx_uda134x_snd_device,

                    &snd_soc_s3c24xx_uda134x);

       platform_device_add_data(s3c24xx_uda134x_snd_device, &s3c24xx_uda134x, sizeof(s3c24xx_uda134x));

       ret = platform_device_add(s3c24xx_uda134x_snd_device);

       if (ret) {

           printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");

           platform_device_put(s3c24xx_uda134x_snd_device);

       }

       return ret;

    }

    Could you please help me & correct me what are all the changes that needs to be done in Davinci-evm.c & am335x-bone-common.dtsi w.r.t L3 bus driver based on DTS similar to s3c24xx_uda134x.c & Mach-mini2440.c

    Kindly do the needful as early as possible as am stuck with this from many days only this is left for my PCM nodes to be created

    Many Many Thanks in advance again

  • Hi Yordan,

    Happy new year!
    Hope you are in vaccation, once after your vaccation, could you please address the above query as early as possible as am stuck in parsing the platform data in uda134x.c for more than 2 weeks

    Many Thanks in advance Yordan,
  • Could you please provide any suggestions or updates w.r.t the above issue as early possible as this is getting delayed from many weeks

    Awaiting for your replies
    Many Thanks in advance
  • Hi,

    Sorry for the delayed response, I was OoO.

    Just to mention, that this is quite a big modification of the sdk.

    The dts file should contain olny basic HW info (keeping the dts simple) about your codec like pin settings, clocks, irq, power etc.. (refer to previous post) & point the compatible codec driver. 
    As per my understanding all other configuration should be done inside the audio codec driver / board file (i.e. in sound/soc/...). As a refernece you can see what is done for tlv320aic codec in am335x-evm.dts & replace the nodes with the data that meeds your use case:
        /*sound node should contain smth like*/
              sound {
                compatible = "ti,da830-evm-audio";         
                ti,model = "AM335x-EVM";
                ti,audio-codec = <&tlv320aic3106>;
                ti,mcasp-controller = <&mcasp1>;
                ti,codec-clock-rate = <12000000>;
                ti,audio-routing =
                    "Headphone Jack",       "HPLOUT",
                    "Headphone Jack",       "HPROUT",
                    "LINE1L",               "Line In",
                    "LINE1R",               "Line In";
            };
       ...................
       ...................
        /*audio codec node*/
                tlv320aic3106: tlv320aic3106@1b {
                    compatible = "ti,tlv320aic3106";
                    reg = <0x1b>;
                    status = "okay";

                    /* Regulators */
                    AVDD-supply = <&vaux2_reg>;
                    IOVDD-supply = <&vaux2_reg>;
                    DRVDD-supply = <&vaux2_reg>;
                    DVDD-supply = <&vbat>;
                };

    As I see from the sources you've given the board files contain setting device pins (and also from your post I get that you've already done that in the dts file); the other configurations (like initializing the codec) could be ported in the specific audio codec driver.

    Hope this is of help.

    Best Regards,
    Yordan

  • Thanks a lot Yordan, Finally it was great breakthrough , And now am able to create PCM nodes,

    But while setting the dai fmt am facing the issue it is saying that it is "unsupported  format in slave mode" in codec driver,

    Even I had set correct formats in davinci-evm.c & uda134x.c & the snd_soc_dai structure also,

    could you please let me know whether am missing anything apart from this & inorder to resolve this issue as early as possible ,

    hope am stuck with this issue only, finally inorder to test my audio playback

    static struct snd_soc_dai_link evm_dai_uda134x = {

    .name = "UDA134x",

    .stream_name = "UDA134x",

    //.cpu_dai_name= "davinci-mcasp.0",

    .codec_dai_name = "uda134x-hifi",

    //.codec_name = "uda134x-codec",

    //.platform_name = "davinci-mcasp.0",

    .ops = &evm_ops,

    .init = evm_uda134x_init,

    .dai_fmt = (SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_DSP_B |

      SND_SOC_DAIFMT_IB_NF),

    };

    static int evm_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 *codec_dai = rtd->codec_dai;

    struct snd_soc_dai *cpu_dai = rtd->cpu_dai;

    struct snd_soc_codec *codec = rtd->codec;

    struct snd_soc_card *soc_card = codec->card;

    int ret = 0;

    unsigned int bclk_freq = evm_get_bclk(params);

    unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)

      snd_soc_card_get_drvdata(soc_card))->sysclk;

    printk("DAVINCIIIIIIIIII UDA134XXXXX HW PARAMS\n");

          printk("DAVINCIIIIIIIIII UDA134XXXXX SYSCLK=%d\n", sysclk);

          printk("DAVINCIIIIIIIIII UDA134XXXXX BCLK FREQQ=%d\n", bclk_freq);

    ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |

    SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);

    if (ret < 0)

    return ret;

    ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |

    SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);

    if (ret < 0)

    return ret;

    /* set the codec system clock */

    ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT);

    if (ret < 0)

    return ret;

    /* set the CPU system clock */

    ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);

    if (ret < 0)

    return ret;

    return 0;

    }

    /* Common DAPM widgets */

    static const struct snd_soc_dapm_widget uda134x_dapm_widgets[] = {

    SND_SOC_DAPM_INPUT("VINL1"),

    SND_SOC_DAPM_INPUT("VINR1"),

    //SND_SOC_DAPM_INPUT("VINL2"),

    //SND_SOC_DAPM_INPUT("VINR2"),

    SND_SOC_DAPM_OUTPUT("VOUTL"),

    SND_SOC_DAPM_OUTPUT("VOUTR"),

    };

    static const struct snd_soc_dapm_route uda134x_dapm_routes[] = {

    { "ADC", NULL, "VINL1" },

    { "ADC", NULL, "VINR1" },

    //{ "ADC", NULL, "VINL2" },

    //{ "ADC", NULL, "VINR2" },

    { "VOUTL", NULL, "DAC" },

    { "VOUTR", NULL, "DAC" },

    };

    static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,

          unsigned int fmt)

    {

    struct snd_soc_codec *codec = codec_dai->codec;

    struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);

    //printk("uda134x_set_dai_fmttttttttttttttttttttt %s fmt: %08X\n", __func__, fmt);

    printk("uda134x_set_dai_fmttttttttttttttttttttt %s: fmt = 0x%x\n", __func__, fmt);

    //fmt = SND_SOC_DAIFMT_MASTER_MASK;

    /* codec supports only full slave mode */

    if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {

    printk(KERN_ERR "%s unsupported slave mode\n", __func__);

    return -EINVAL;

    }

    /* no support for clock inversion */

    if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {

    printk(KERN_ERR "%s unsupported clock inversion\n", __func__);

    return -EINVAL;

    }

    /* We can't setup DAI format here as it depends on the word bit num */

    /* so let's just store the value for later */

    uda134x->dai_fmt = fmt;

    return 0;

    }

    [    1.302774] DAVINCI EVM PROBE FOR UDA1345TSSSSSSSSS CODEC SoC Audio driver

    [    1.310076] DAVINCI EVM PROBE FOR UDA1345 CODEC DAI -> CODEC OF NODE IS SUCCESSFULL ti,audio-codec

    [    1.319469] DAVINCI EVM PROBE FOR UDA1345 CODEC DAI -> CPU OF NODE IS SUCCESSFULL ti,mcasp-controller

    [    1.329146] DAVINCI EVM PROBE FOR UDA1345 CODEC snd_soc_of_parse_card_name  ti,model is SUCCESSSFULL

    [    1.338725] DAVINCI EVM PROBE FOR UDA1345 CODEC MCLKKK ti,codec-clock is SUCCESSSFULL

    [    1.346997] DAVINCI EVM PROBE FOR UDA1345 CODEC DRVDATA SUCCESSFULL

    [    1.353746] SRINIII CLIENT DRIVER UDA134X SoC Audio Codec probe....!!!!!!!!!!!!!!!!!!!!

    [    1.374524] mmc1: BKOPS_EN bit is not set

    [    1.380048] SWITCHING TO UDA134X_UDA1345 SNDDDDDDDDDDD CONTROLSSSSSSSSSS

    [    1.387887] davinci_evm sound.4:  uda134x-hifi <-> 48038000.mcasp mapping ok

    [    1.395340] uda134x_set_dai_fmttttttttttttttttttttt uda134x_set_dai_fmt: fmt = 0x1305

    [    1.403561] uda134x_set_dai_fmt unsupported slave mode

    [    1.408948] uda134x-codec uda134x.3: ASoC: Failed to set DAI format: -22

    [    1.416070] uda134x-codec uda134x.3: ASoC: Failed to create VOUTR debugfs file

    [    1.423658] uda134x-codec uda134x.3: ASoC: Failed to create VOUTL debugfs file

    [    1.431252] mmc1: new high speed MMC card at address 0001

    [    1.437134] uda134x-codec uda134x.3: ASoC: Failed to create VINR1 debugfs file

    [    1.445071] mmcblk1: mmc1:0001 MMC02G 1.78 GiB

    [    1.449936] mmcblk1boot0: mmc1:0001 MMC02G partition 1 1.00 MiB

    [    1.456175] uda134x-codec uda134x.3: ASoC: Failed to create VINL1 debugfs file

    [    1.465462] mmcblk1boot1: mmc1:0001 MMC02G partition 2 1.00 MiB

    [    1.474222] oprofile: no performance counters

    [    1.479051]  mmcblk1: p1 p2

    [    1.482807] oprofile: using timer interrupt.

    [    1.487520] TCP: cubic registered

    [    1.491031] Initializing XFRM netlink socket

    [    1.496429] NET: Registered protocol family 17

    [    1.501230] NET: Registered protocol family 15

    [    1.935338] ALSA device list:

    [    1.938468]   #0: TI UDA1345TS

    ALSA: Restoring mixer settings...

    No state is present for card UDA1345TS

    Found hardware: "TI_UDA1345TS" "" "" "" ""

    Hardware is initialized using a generic method

    No state is present for card UDA1345TS

    Could you please kindly help me why am getting "unsupported slave mode" what is the issue & in the log at the end it is saying "No state is present for card UDA1345TS" could you please let me know whether it leads to any serious issues in future & any suggestions for fixing the same

    Many Many Thanks in advance once again for your prompt responses

  • I fixed the issue w.r.t dai_fmt Yordan, it was supposed to be  

    .dai_fmt = (SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S |

      SND_SOC_DAIFMT_NB_NF),

    instead of

    .dai_fmt = (SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_DSP_B |

      SND_SOC_DAIFMT_IB_NF),

    Am seeing the below messages, as this is final error messages am seeing could you please help me only sorting out this issues, so that I can verify codec playback without any errors or warnings

    Also could you please let me know whether these errors/warnings would cause serious issue in audio playback or if not could you please let me know whether this is ignorable for my inital playback testing on audio codec, so that I can try to rectify these error/warnings before I test this on hardware

    [    0.491182] uuuuuuuuuda134x_set_dai_fmttttttttttttttttttttt uda134x_set_dai_fmt: fmt = 0x4001
    [    1.408011] uda134x-codec uda134x.3: ASoC: Failed to create VOUTR debugfs file
    [    1.415600] uda134x-codec uda134x.3: ASoC: Failed to create VOUTL debugfs file
    [    1.423191] uda134x-codec uda134x.3: ASoC: Failed to create VINR1 debugfs file
    [    1.430788] uda134x-codec uda134x.3: ASoC: Failed to create VINL1 debugfs file

    ALSA: Restoring mixer settings...
    No state is present for card UDA1345TS
    Found hardware: "TI_UDA1345TS" "" "" "" ""
    Hardware is initialized using a generic method
    No state is present for card UDA1345TS

    Finally about reach my destination, Once again many thanks Yordan for your prompt support w.r.t this thread & would appreciate a lot

    Many Many Thanks a lot in advance again

  • Hi Srini,

    I am not an audio /alsa/ expert (need to dig a bit more into this), but I think those messages "ASoC: Failed to create ....." are warnings from sound/soc-core.c & sound/soc-dapm.c drivers.
    If you are able to boot your device you should test audio & try to overcome these warnings with amixer settings from user space (command line).

    Best Regards,
    Yordan

  • Thanks a lot Yordan for your quick responses,

    As of now I ignored the warnings & I tried to play using aplay with different samples but it is saying that uda134x_hw_params unsupported fs, I hope the mclk towards mcasp side needs to be adjusted, could you please let me know how this can achieved or please correct me if my understanding is wrong


    uda134x.c

    static int uda134x_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
    {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_codec *codec = rtd->codec;
        struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
        u8 hw_params;

        if (substream == uda134x->slave_substream) {
            pr_debug("%s ignoring hw_params for slave substream\n",
                 __func__);
            return 0;
        }

        hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
        hw_params &= STATUS0_SYSCLK_MASK;
        hw_params &= STATUS0_DAIFMT_MASK;

        printk("%s sysclk: %d, rate:%d\n", __func__,
             uda134x->sysclk, params_rate(params));

        /* set SYSCLK / fs ratio */
        switch (uda134x->sysclk / params_rate(params)) {

        case 512:
            break;
        case 384:
            hw_params |= (1<<4);
            break;
        case 256:
            hw_params |= (1<<5);
            break;
        default:
            printk(KERN_ERR "%s unsupported fs\n", __func__);
            return -EINVAL;
        }

        printk("%s dai_fmt: %d, params_format:%d\n", __func__,
             uda134x->dai_fmt, params_format(params));

        /* set DAI format and word length */
        switch (uda134x->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
        case SND_SOC_DAIFMT_I2S:
            break;
        case SND_SOC_DAIFMT_RIGHT_J:
            switch (params_format(params)) {
            case SNDRV_PCM_FORMAT_S16_LE:
                hw_params |= (1<<1);
                break;
            case SNDRV_PCM_FORMAT_S18_3LE:
                hw_params |= (1<<2);
                break;
            case SNDRV_PCM_FORMAT_S20_3LE:
                hw_params |= ((1<<2) | (1<<1));
                break;
            default:
                printk(KERN_ERR "%s unsupported format (right)\n",
                       __func__);
                return -EINVAL;
            }
            break;
        case SND_SOC_DAIFMT_LEFT_J:
            hw_params |= (1<<3);
            break;
        default:
            printk(KERN_ERR "%s unsupported format\n", __func__);
            return -EINVAL;
        }

        uda134x_write(codec, UDA134X_STATUS0, hw_params);

        return 0;
    }

    Logs:

    =====

    1) root@am335x-evm:/home/wavfiles# aplay -D hw:0,0 guitar.wav

    Playing WAVE 'guitar.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Mono

    aplay: set_params:1108: Channels count non available

    2) root@am335x-evm:/home/wavfiles# aplay guitar.wav

    Playing WAVE 'guitar.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Mono[  184.339081] DAVINCIIIIIIIIII UDA134XXXXX HW PARAMS

    [  184.347114] DAVINCIIIIIIIIII UDA134XXXXX SYSCLK=12288000

    [  184.352837] DAVINCIIIIIIIIII UDA134XXXXX BCLK FREQQ=1411200

    [  184.358682] uda134x_hw_params sysclk: 12288000, rate:44100

    [  184.364436] uda134x_hw_params unsupported fs

    [  184.368917] uda134x-codec uda134x.3: ASoC: can't set uda134x-hifi hw params: -22

    aplay: set_params:1166: Unable to install hw params:

    ACCESS:  RW_INTERLEAVED

    FORMAT:  S16_LE

    SUBFORMAT:  STD

    SAMPLE_BITS: 16

    FRAME_BITS: 16

    CHANNELS: 1

    RATE: 44100

    PERIOD_TIME: (46439 46440)

    PERIOD_SIZE: 2048

    PERIOD_BYTES: 4096

    PERIODS: 16

    BUFFER_TIME: (743038 743039)

    BUFFER_SIZE: 32768

    BUFFER_BYTES: 65536

    TICK_TIME: 0

    root@am335x-evm:/home/wavfiles# ls                                                                                                            

    8khz_16 bit_mono_ PCM.wav

    Media-Convert_test2_PCM_Mono_VBR_8SS_48000Hz.wav

    NeroSoundTrax_test8_PCM_Mono_VBR_16SS_48000Hz.wav

    a2002011001-e02-16kHz.wav

    a2002011001-e02-8kHz.wav

    guitar.wav

    guitar_44khz.wav

    guitar_8khz.wav

    root@am335x-evm:/home/wavfiles# aplay a2002011001-e02-8kHz.wav

    Playing WAVE 'a2002011001-e02-8kHz.wav' : Signed 16 bit Li[  588.903761] DAVINCIIIIIIIIII UDA134XXXXX HW PARAMS

    ttle Endian, Rate 8000 Hz, Stereo

    [  588.911769] DAVINCIIIIIIIIII UDA134XXXXX SYSCLK=12288000

    [  588.920364] DAVINCIIIIIIIIII UDA134XXXXX BCLK FREQQ=256000

    [  588.926119] uda134x_hw_params sysclk: 12288000, rate:8000

    [  588.931781] uda134x_hw_params unsupported fs

    [  588.936263] uda134x-codec uda134x.3: ASoC: can't set uda134x-hifi hw params: -22

    aplay: set_params:1166: Unable to install hw params:

    ACCESS:  RW_INTERLEAVED

    FORMAT:  S16_LE

    SUBFORMAT:  STD

    SAMPLE_BITS: 16

    FRAME_BITS: 32

    CHANNELS: 2

    RATE: 8000

    PERIOD_TIME: 125000

    PERIOD_SIZE: 1000

    PERIOD_BYTES: 4000

    PERIODS: 16

    BUFFER_TIME: 2000000

    BUFFER_SIZE: 16000

    BUFFER_BYTES: 64000

    TICK_TIME: 0

    root@am335x-evm:/home/wavfiles# aplay

    8khz_16 bit_mono_ PCM.wav

    Media-Convert_test2_PCM_Mono_VBR_8SS_48000Hz.wav

    NeroSoundTrax_test8_PCM_Mono_VBR_16SS_48000Hz.wav

    a2002011001-e02-16kHz.wav

    a2002011001-e02-8kHz.wav

    guitar.wav

    guitar_44khz.wav

    guitar_8khz.wav

    Hz.wav 335x-evm:/home/wavfiles# aplay Media-Convert_test2_PCM_Mono_VBR_8SS_48000H

    Playing WAVE 'Media-Convert_test2_PCM_Mono_VBR_8SS_48000Hz.wav' [  768.863916] DAVINCIIIIIIIIII UDA134XXXXX HW PARAMS

    : Unsigned 8 bit, Rate 44100 Hz, Mono

    [  768.872450] DAVINCIIIIIIIIII UDA134XXXXX SYSCLK=12288000

    [  768.881397] DAVINCIIIIIIIIII UDA134XXXXX BCLK FREQQ=705600

    [  768.887152] uda134x_hw_params sysclk: 12288000, rate:44100

    [  768.892905] uda134x_hw_params unsupported fs

    [  768.897387] uda134x-codec uda134x.3: ASoC: can't set uda134x-hifi hw params: -22

    aplay: set_params:1166: Unable to install hw params:

    ACCESS:  RW_INTERLEAVED

    FORMAT:  U8

    SUBFORMAT:  STD

    SAMPLE_BITS: 8

    FRAME_BITS: 8

    CHANNELS: 1

    RATE: 44100

    PERIOD_TIME: (92879 92880)

    PERIOD_SIZE: 4096

    PERIOD_BYTES: 4096

    PERIODS: 16

    BUFFER_TIME: (1486077 1486078)

    BUFFER_SIZE: 65536

    BUFFER_BYTES: 65536

    TICK_TIME: 0

    root@am335x-evm:/home/wavfiles#

    Kindly do the needful as early as possible

    Awaiting for your replies,

    Many Thanks in advance

  • Dear Yordan,

    As my uda1345ts supports 256, 384, & 512fs system clocks, Could you please let me know how mcasp i2s mode clocks can be changed to 256fs, 384fs & 512fs in mcasp configuration as I was unable to find this configuration in am335x TRM

    Kindly do the needful as early as possible

    Awaiting for your replies,
    Many Thanks in advance
  • Hi Srini,

    MCASP clocks are done by writing to the MCASP ACLKXCTL[11:0]CLKXDIV & AHCLKXCTL[11:0] HCLKXDIV bit fields.

    Device level configurations (like digital audio interface links definition and configuration, setup power supplies and clocks and declaring machine-level DAPM widgets and connect them with codec widget is done in the machine driver. See: http://processors.wiki.ti.com/index.php/Sitara_Linux_SDK_Audio_DAC_Example#ALSA_Machine_Layer_Configuration
    Specifically you should refer to sound/soc/davinci/davinci-evm.c & sound/soc/davinici/davinci-mcasp.c files. Clock settings for MCLK are done in evm_slave_codec_hw_params() function; essentially in the lines:
    ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk / bclk_freq);
    ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_IN);.
    you are writing to the above listed bit fields.

    Best Regards,
    Yordan
  • Forgot to mention, see also mcasp_i2s_hw_param() function in sound/soc/davinci/davinci-mcasp.c

    Best Regards,
    Yordan
  • Thanks a lot for your info Yordan,

    1) I need MCLK to be scaled for UDA1345TS to 256, 384 & 512fs in I2S mode, what is the clock divider values that needs to set inorder to obtain 256, 384 & 512fs in HCLKDIV of AHCLKXCTL as I didn't understand what is "AUXCLK"

    Could you please let what are the clock divider values that needs to be set for 256, 384 & 512fs

    Kindly do the needful as early as possible, inorder to resolve my earlier posted issue

    2) As am confused with terminologies sysclk, does sysclk means MCLK??? because am setting the MCLK as 12288000, but the below link says that "the internal 24 MHz clock as sysclk for the McASP" , could you please clarify on the same as am bit confused with this

    http://processors.wiki.ti.com/index.php/Sitara_Linux_SDK_Audio_DAC_Example#ALSA_Machine_Layer_Configuration

    The next important line is the following:

    ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);

    This line is making sure that ALSA knows that we will be using the internal 24 MHz clock as sysclk for the McASP, rather than using an external oscillator as is the case with many Sitara EVMs.

     

    Kindly do the needful as early as possible,

    Awaiting for your replies

    Many Thanks in advance

  • Could you please provide any inputs w.r.t above queries, as this is taking time to understand TRM
  • Hi Srini,

    My understanding is that MCLK is the AHCLKX/AHCLKR clock, and as you can see the AHCLKX clock is derived from the internal functional clock supplied to MCASP through PRCM (AUXCLK), which is the SYSCLK = 24MHz

    Since you use 12MHz clock you are setting the AHCLKX divider to 2 (AHCLKXCTL[11:0]HCLKXDIV = 0x1). I am still figuring out how the master clock should be calculated according to your fs (as I said, I am not an audio expert), in the mean time try using the higher clock (24MHz) AHCLKXCTL[11:0]HCLKXDIV = 0x0 (divider = 1) to see if there will be any change in the behaviour of your system.

    Best Regards,
    Yordan

  • Hi Srini,

    As I suspected, you should use the master clock to be 24 MHz (AHCLKX devider HCLKXDIV should be 1). And set the bit clock deviders according to your use case. BCLK devicers are set by: ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);
    BCLK is calculated by the following formula:
    BCLK=2*SampleRate*BitsPerSample

    This is confirmed by the DAC Example you listed in your initial post & an Android app note I found.
    You can also use the following ALSA user space guide to properly set your audio pipe through user space commands: http://processors.wiki.ti.com/index.php/Sitara_SDK_Linux_Audio_ALSA_User_Space

    Best Regards,
    Yordan
  • Dear Yordan,

    Many Thanks a lot for your prompt responses & quick inputs,,

    1) Am sorry, I require 12Mhz clock only Yordan,  because 12288000/48000 = 256, this is required as per my client driver as shown below

    Client driver :/sound/soc/codecs/uda134x.c

    static int uda134x_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params,
        struct snd_soc_dai *dai)
    {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_codec *codec = rtd->codec;
        struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec);
        u8 hw_params;

        if (substream == uda134x->slave_substream) {
            pr_debug("%s ignoring hw_params for slave substream\n",
                 __func__);
            return 0;
        }

        hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
        hw_params &= STATUS0_SYSCLK_MASK;
        hw_params &= STATUS0_DAIFMT_MASK;

        printk("UDA1345TSSSSSSSSSSSS CLOCKS %s sysclk: %d, rate:%d\n", __func__,
             uda134x->sysclk, params_rate(params));

        printk("UDA1345TSSSSSSSSSSSS FORMATS %s dai_fmt: %d, params_format:%d\n", __func__,
             uda134x->dai_fmt, params_format(params));

        /* set SYSCLK / fs ratio */
        switch (uda134x->sysclk / params_rate(params)) {
        case 512:
            printk(KERN_ERR "UDA1345TSSSSSSSSSSSS SYSCLK / fs ratio is 512\n");
            break;
        case 384:
            printk(KERN_ERR "UDA1345TSSSSSSSSSSSS SYSCLK / fs ratio is 384\n");
            hw_params |= (1<<4);
            break;
        case 256:
            printk(KERN_ERR "UDA1345TSSSSSSSSSSSS SYSCLK / fs ratio is 256\n");
            hw_params |= (1<<5);
            break;
        default:
            printk(KERN_ERR "%s unsupported fs\n", __func__);
            return -EINVAL;
        }

    logs:

    Playing WAVE 'Source-Connect_48khz_16bit.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono[   90.430480]
    [   90.430480] DAVINCIIIIIIIIII UDA134XXXXX SYSCLK=12288000
    [   90.441136] DAVINCIIIIIIIIII UDA134XXXXX BCLK FREQQ=1536000

    [   90.485231] UDA1345TSSSSSSSSSSSS CLOCKS uda134x_hw_params sysclk: 12288000, rate:48000
    [   90.493620] UDA1345TSSSSSSSSSSSS FORMATS uda134x_hw_params dai_fmt: 16385, params_format:2
    [   90.502386] UDA1345TSSSSSSSSSSSS SYSCLK / fs ratio is 256
    [   90.508110] uda134x_hw_params dai_fmt: 16385, params_format:2
    [   90.514207] UDA1345TSSSSSSSSSSSS FORMAT SND_SOC_DAIFMT_I2S
    root@am335x-evm:/home/wavfiles#

    2) I modified as per your suggestions, but since I need 12mhz with the existing dts changes ie.,  ti,codec-clock-rate = <12288000>; & as per your snd_soc_dai_set_clkdiv changes as shown below, but still am seeing 24Mhz clock on the cscope where I expected 12Mhz clock on cscope instead of 24mhz

    I think somehwere else also I need to configure to 12mhz , I hope the below api doesn't configure for 12mhz , could you please let me know how to get my mclk 12mhz on cscope is there any other place I need to change the configuration or how this below api can be modified for 12mhz

     ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);

    3) Could you please clarify my doubts w.r.t the evm_hw_params configuration, & could you please rewrite & send me only the evm_hw_params function in davinci_evm.c if possible or please correct me if am missing any other api other than the below configurations in evm_hw_params done by me

    Davinci-evm.c

    static int evm_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 *codec_dai = rtd->codec_dai;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_card *soc_card = codec->card;
        int ret = 0;
        unsigned int bclk_freq = evm_get_bclk(params);
        unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
                   snd_soc_card_get_drvdata(soc_card))->sysclk;

         
           printk("DAVINCIIIIIIIIII UDA134XXXXX SYSCLK=%d\n", sysclk);
           printk("DAVINCIIIIIIIIII UDA134XXXXX BCLK FREQQ=%d\n", bclk_freq);

    >>As you suggested I have set the below in snd_soc_dai_set_clkdiv, could you please confirm whether this is correct or not

         
        ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);
        if (ret < 0) {
            printk("DAVINCIIIIIIIIII snd_soc_dai_set_clkdiv can't set CPU DAI clock divider %d\n", ret);
            return ret;
        }

           printk("DAVINCIIIIIIIIII AFTER SCALINGGGGGGGG UDA134XXXXX SYSCLK=%d\n", sysclk);
           printk("DAVINCIIIIIIIIII AFTER SCALINGGGGGGGG UDA134XXXXX BCLK FREQQ=%d\n", bclk_freq);

    >> Could you please confirm whether the argument should be SND_SOC_CLOCK_IN in snd_soc_dai_set_sysclk(cpu_dai, 0,..) or SND_SOC_CLOCK_OUT


            /* Set McASP sysclk from AHCLKX sourced from ATL */
        ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
        if (ret < 0)
            dev_err(soc_card->dev, "can't set CPU DAI sysclk %d\n", ret);

    >> Could you please confirm whether the argument should be SND_SOC_CLOCK_IN in snd_soc_dai_set_sysclk(codec_dai, 0,..) or SND_SOC_CLOCK_OUT


        /* Set MCLK as clock source for UDA1345TS*/
        ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_IN); // to be rechecked again
        if (ret < 0)
            return ret;


        return ret;

    }

    Kindly do the needful as early as possible

    Many Thanks in advance Yordan once agian for your prompt support & responses

  • Dear Yordan,

    1) Could you please help me in modifying the apis in evm_hw_params function inorder to achieve 12Mhz (256*48khz as this 256 multiples freq supported by my codec) master clock & bit clock 1.536Mhz (48khz*16*2)

    2) Could you please confirm whether it should be  SND_SOC_CLOCK_IN or  SND_SOC_CLOCK_OUT for codec_dai

       /* Set MCLK as clock source for UDA1345TS*/

       ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_IN);

    Kindly do the needful as early as possible if I get the MCLK & BCK correctly with above figures, hope I wouldn't face any troubles in getting the data at the output of the codec

    Awaiting for your replies

    Many Thanks in advance,

  • Dear Yordan,

    1) Could you please help me in modifying the apis in evm_hw_params function inorder to achieve 12Mhz (256*48khz as this 256 multiples freq supported by my codec) master clock & bit clock 1.536Mhz (48khz*16*2)

    2) Could you please confirm whether it should be SND_SOC_CLOCK_IN or SND_SOC_CLOCK_OUT for codec_dai in the below api

    /* Set MCLK as clock source for UDA1345TS*/

    ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_IN);

    Kindly do the needful as early as possible if I get the MCLK & BCK correctly with above figures, hope I wouldn't face any troubles in getting the data at the output of the codec

    Awaiting for your replies

    Many Thanks in advance,
  • Dear Yordan,

    1) Could you please provide any suggestions or inputs w.r.t my above 2 queries

    2) With the below api modifications I scoped out the ahclkx pin, I was able to get MCLK = 12MHZ, & bitclock = 1.500 MHz, where I was supposed to get 1.536Mhz & lrclk 46.89Khz instead of 48Khz,

    Could you please let me why there is so much deviations from 1.536Mhz to 1.500 Mhz w.r.t bitclock & lrclk from 48khz to 46.89Khz


    I hope because this, am not getting any analog output at the end of the codec, could you please suggest is there any ways that can be corrected to 1.536Mhz & 48khz w.r.t bit clock & lrclk

    static int evm_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 *codec_dai = rtd->codec_dai;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_card *soc_card = codec->card;
        int ret = 0;
        unsigned int bclk_freq = evm_get_bclk(params);
        unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
                   snd_soc_card_get_drvdata(soc_card))->sysclk;
       
          printk("\nDAVINCIIIIIIIIII UDA134XXXXX SYSCLK=%d\n", sysclk);
        printk("DAVINCIIIIIIIIII UDA134XXXXX BCLK FREQQ=%d\n", bclk_freq);
        printk("DAVINCIIIIIIIIII UDA134XXXXX SYSCLK/BCLK_FREQ =%d\n", sysclk/bclk_freq);
        

    #if 1    
        ret = snd_soc_dai_set_clkdiv(cpu_dai, 0, 2);
        if (ret < 0) {
            printk("DAVINCIIIIIIIIII MCLKKK snd_soc_dai_set_clkdiv can't set CPU DAI clock divider %d\n", ret);
            return ret;
        }
    #endif

    #if 1

        ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);
        if (ret < 0) {
            printk("DAVINCIIIIIIIIII BCLKKK can't set CPU DAI clock divider %d\n",
                ret);
            return ret;
        }
    #endif

    ////////////// below code don't touch is required compulsorily

    Could you please confirm w.r.t the cpu_dai & codec_dai whether it should be SND_SOC_CLOCK_OUT or SND_SOC_CLOCK_IN

            /* Set McASP sysclk from AHCLKX sourced from ATL */
        ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
        if (ret < 0)
            dev_err(soc_card->dev, "can't set CPU DAI sysclk %d\n", ret);


        /* Set MCLK as clock source for UDA1345TS ie., set the codec system clock */
        ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT); // SND_SOC_CLOCK_OUT or SND_SOC_CLOCK_IN needs to be rechecked again
        if (ret < 0)
            return ret;

        return 0;

    }


    Many Many Thanks in advance for your support

  • Dear Yordan,

    Could you please provide any inputs or suggestions w.r.t my above queries as early as possible, sorry to push you hard

    Thanks in advance
  • Hi Srini,

    Sorry for the delayed response.

    Here is what I can answer of your questions:

    Srini S said:
    Could you please confirm w.r.t the cpu_dai & codec_dai whether it should be SND_SOC_CLOCK_OUT or SND_SOC_CLOCK_IN

    As I understand you use the internally generated 24MHz sysclk, right? If so then you should use SND_SOC_CLOCK_OUT. If you use an external oscillator to feed the sysclk to your AM335x McASP IP, then you should use SND_SOCL_CLOCK_IN.

    As per my understanding you shouldn't modify the static int evm_hw_params() function in davinci-evm.c.

    With the lines:
     

    Srini S said:
    #if 1    
        ret = snd_soc_dai_set_clkdiv(cpu_dai, 0, 2);

    you force the ALSA to set the MCLK devider to 2, giving you 12MHz clock.  And immediately after that: 

    Srini S said:
    #if 1

        ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);

    You force the alsa to set the BCLK divider to sysclk/bclk_freq.

    Where as per my understanding static int evm_hw_params() function should be left as is:
      static int evm_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 *codec_dai = rtd->codec_dai;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_card *soc_card = codec->card;
        int ret = 0;
        unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
                   snd_soc_card_get_drvdata(soc_card))->sysclk;

        /* set the codec system clock */
        ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
        if (ret < 0)
            return ret;

        /* set the CPU system clock */
        ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
        if (ret < 0)
            return ret;

        return 0;
    }


    And later in the davinci-evm.c you need to create your own function and populate it with the corresponding clock dividers, that match your use case: 

    static int evm_uda134x_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 *codec_dai = rtd->codec_dai;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_card *soc_card = codec->card;
        unsigned int bclk_freq = evm_get_bclk(params);
        int ret = 0;
        unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
                   snd_soc_card_get_drvdata(soc_card))->sysclk;

        printk("\nDAVINCIIIIIIIIII UDA134XXXXX SYSCLK=%d\n", sysclk);
        printk("DAVINCIIIIIIIIII UDA134XXXXX BCLK FREQQ=%d\n", bclk_freq);
        printk("DAVINCIIIIIIIIII UDA134XXXXX SYSCLK/BCLK_FREQ =%d\n", sysclk/bclk_freq);

        #if 1  
        ret = snd_soc_dai_set_clkdiv(cpu_dai, 0, 2);
        if (ret < 0) {

            printk("DAVINCIIIIIIIIII MCLKKK snd_soc_dai_set_clkdiv can't set CPU DAI clock divider %d\n", ret);
            dev_err(soc_card->dev, "can't set CPU DAI clock divider %d\n", ret);

            return ret;
        }

        #endif

        #if 1
        ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);    //Alsa calculates the BCLK freq according to the audio played & sets the clkdiv...
        if (ret < 0) {
            printk("DAVINCIIIIIIIIII BCLKKK can't set CPU DAI clock divider %d\n", ret);
            return ret;
        }

        #endif
        /* Set MCLK as clock source for UDA1345TS ie., set the codec system clock*/
        ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT);    //Tell alsa to use the internally generated clock as master clock to UDA1345TS
        if (ret < 0)
            return ret;

        /* Set McASP sysclk from AHCLKX sourced from ATL */
        ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);   //Tell alsa to use the internally generated clock as sysclk for MCASP
        if (ret < 0)
            dev_err(soc_card->dev, "can't set CPU DAI sysclk %d\n", ret);

        return ret;
    }

    Try similar approach to see if audio framework will glue the codec & MCASP settings correctly. NOTE: This is just a suggestion; I cannot test this, because I use UNMODIFIED AM335x EVM.

    Best Regards,
    Yordan

  • Dear Yordan,

    Thanks a lot for your quick responses Yordan, with your prompt support only am proceeding further

    As you suggested I create own function as shown above & I scoped out the waveforms but still am unable to get the audio data out of codec

    I scoped out the waveforms

    MCLK am getting as 12.00Mhz instead of 12.288000 Mhz (256*fs)

    Bclk am getting as 1.500Mhz instead of 1.536Mhz (48Khz*16*2)

    Lrclk am getting as 46.89 Khz instead of 48khz (which should be same as sampling frequency)

    Could you please let me know whether this values ie., 12.00Mhz, 1.500Mhz & 46.89 Khz are acceptable or should I get accurately 12.288000 Mhz, 1.536Mhz & 48Khz  inorder to get the analog audio data from codec

    In order to get accurately, could you please let me know whether any more mcasp register settings needs to be done

    Kindly do the needful as early as possible

    Many Many Thanks in advance again & would appreciate a lot for all your support so far

  • Dear Yordan,


    Am using internally generated 24Mhz sysclk & no external clock being used, so could you please provide any suggestions or inputs  w.r.t my above queries w.r.t MCLK, BCLK & LRCLK inorder to get these values accurately ie., 12.288000MHz, 1.536Mhz, 48Khz the necessary changes that needs to be done towards mcasp side ie., any register settings to be done to achieve these accurate values

    Kindly do the needful as early as possible, once again sorry to push you very hard


    Awaiting for your replies
    Many Thanks in advance,

  • Hi Srini,

    The BCLK & LRCKL should meet your use case... in order to have a quality playback (output) on the codec.  It's worth taking a look at davinci-mcasp.c file & play with the code if needed (if your use case is not met within the settings done there).

    Maybe try adding the

           mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, AHCLKX);
           mcasp_set_bits(mcasp, DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXE);

    lines in the appropriate case in the switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) in davinci_mcasp_set_dai_fmt() function.

    Also have a look at Section 22.2.5 Clock and Frame Sync Generators in AM335x TRM... it may give you some ideas for tuning your code.

    Best Regards,

    Yordan

  • Dear Yordan,

    Thanks a lot Yordan once again for your quick responses,

    1) I'm trying to understand TRM ie., in section 22.2.2 McASP Clock and Reset Management, it says the auxclk is 26Mhz

    auxclk 26 MHz CLK_M_OSC pd_per_mcasp_fclk

    But the below link says

    http://processors.wiki.ti.com/index.php/Sitara_Linux_SDK_Audio_DAC_Example

    sysclock is the clock source that is fed to the McASP internally. It is 24 MHz on all Sitara EVMs. ALSA knows what this value is, which is why we request it as a variable.

    As am bit confused, Could you please clarify my doubt whether this sysclock is same as auxclk???, if sysclk is same as auxclk,  I didn't find anywhere that sysclock ie., fed to mcasp is 24Mhz in mcasp controller section of TRM 

    Could you please clarify this doubt

    2) Could you please clarify my doubt w.r.t routing as well, I suspect routing part, could you please confirm that the routing part what ever it is in my client driver(ie., sound/soc/codecs/uda134x.c), I have added the same  in davinci-evm.c & dtsi as shown below, could you please let me know whether this routing part is correct or wrong

    /* Common DAPM widgets */
    static const struct snd_soc_dapm_widget uda134x_dapm_widgets[] = {
        SND_SOC_DAPM_INPUT("VINL1"),
        SND_SOC_DAPM_INPUT("VINR1"),
        SND_SOC_DAPM_INPUT("VINL2"), /// to be removed for uda1345ts
        SND_SOC_DAPM_INPUT("VINR2"), /// to be removed for uda1345ts
        SND_SOC_DAPM_OUTPUT("VOUTL"),
        SND_SOC_DAPM_OUTPUT("VOUTR"),
    };

    static const struct snd_soc_dapm_route uda134x_dapm_routes[] = {
        { "ADC", NULL, "VINL1" },
        { "ADC", NULL, "VINR1" },
        { "ADC", NULL, "VINL2" }, /// to be removed for uda1345ts
        { "ADC", NULL, "VINR2" }, /// to be removed for uda1345ts
        { "VOUTL", NULL, "DAC" },
        { "VOUTR", NULL, "DAC" },
    };

    static int evm_uda134x_init(struct snd_soc_pcm_runtime *rtd)
    {
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_dapm_context *dapm = &codec->dapm;
        struct device_node *np = codec->card->dev->of_node;
        int ret;

        snd_soc_dapm_new_controls(dapm, uda134x_dapm_widgets,
                      ARRAY_SIZE(uda134x_dapm_widgets));

        if (np) {
            ret = snd_soc_of_parse_audio_routing(codec->card,
                                 "ti,audio-routing");
            if (ret)
                return ret;

        } else {
            /* Set up davinci-evm specific audio path audio_map */
            printk("DAVINCIIIIIIIIIII UDA134XXXXX  DAPM ROUTING\n");
            snd_soc_dapm_add_routes(dapm, uda134x_dapm_routes, ARRAY_SIZE(uda134x_dapm_routes));
        }


        snd_soc_dapm_enable_pin(dapm, "VINL1"),
        snd_soc_dapm_enable_pin(dapm, "VINR1"),
        snd_soc_dapm_enable_pin(dapm, "VINL2"), /// to be removed for uda1345ts
        snd_soc_dapm_enable_pin(dapm, "VINR2"), /// to be removed for uda1345ts


        snd_soc_dapm_enable_pin(dapm, "VOUTL");
        snd_soc_dapm_enable_pin(dapm, "VOUTR");
        

        return 0;
    }

    am335x-boneblack.dtsi

            sound { 
                            compatible = "ti,uda134x-audio-codec"; 
                ti,model = "TI UDA1345TS"; 
                            //ti,model = "AM335x-EVM"; 
                            ti,audio-codec = <&uda134x>; 
                            ti,mcasp-controller = <&mcasp0>; 
                            /*ti,codec-clock-rate = <24000000>;*/ 
                ti,codec-clock-rate = <12288000>; 
                            ti,audio-routing = 
                    "ADC",       "VINL1", 
                    "ADC",       "VINR1", 
                    "ADC",       "VINL2", 
                    "ADC",       "VINR2", 
                    "VOUTL",               "DAC", 
                    "VOUTR",               "DAC"; 

             };

    Many Thanks in advance again,

  • Dear Yordan,

    1) Could you please provide any inputs w.r.t AUXCLK & routing w.r.t above query

    2) And in section 22.3.5.4 Clocking Examples

    22.3.5.4 Clocking Examples

    Some examples of processes using the McASP clocking and frame flexibility are:

    • Receive data from a DVD at 48 kHz, but output up-sampled or decoded audio at 96 kHz or 192 kHz.

    This could be accomplished by inputting a high-frequency master clock (for example,

    512 × receive FS), receiving with an internally-generated bit clock ratio of divide-by-8, and transmitting

    with an internally-generated bit clock ratio of divide-by-4 or divide-by-2. (I didn't understand this highlighted statement, where is this done in the davinci-mcasp.c file????)

    • Transmit/receive data based on one sample rate (for example, 44.1 kHz), and transmit/receive data at

    a different sample rate (for example, 48 kHz).

    In my case as well I would be receving 256*fs (where fs = 48Khz) & receiving with an internally-generated bit clock ratio of divide-by-8 & where should I do  this 

    and transmitting with an internally-generated bit clock ratio of divide-by-4 or divide-by-2

     

    Kindly do the needful as early as possible, with this I would be able to step further

     

    Many Thanks a lot in advance & would appreciate a lot for all your support provided so far

  • Dear Yordan,

    Could you please provide any inputs w.r.t my 2 queries posted above as early as possible

    Many Thanks in advance
  • Dear Yordan,

    Am awaiting for your replies, Could you please provide any inputs w.r.t my 2 queries posted above as early as possible

    Many Thanks in advance
  • Hi Srini,

    Regarding the routing:

                    "ADC",       "VINL1",

                   "ADC",       "VINR1",

                   "ADC",       "VINL2",

                   "ADC",       "VINR2",

                   "VOUTL",               "DAC",

                   "VOUTR",               "DAC";  

    The above routing is correct, but I am not aware of your use case. As I understand, you are working on a custom AM335x board. Try adopting the audio routing of the board you've referenced while designing your custom board.

    For example if during hw design you referenced AM335x Starter Kit, use the routing presented in am335x-evmsk.dts. If you've referenced AM335x EVM try using the routing in am335x-evm.dts

    Regarding your questions about AUXCLK, see Figure 22-1. McASP Block Diagram in TRM. AUXCLK is the internal clock source that feeds MCASP AHCLKX/ACLKX/AFSX; all these clocks are derived from auxclk after being divided with the according clock divider. 

    Dividers are NOT calculated in davinci-mcasp.c, but in the *_hw_params() functions in  davinci-evm.c

    Best Regards,

    Yordan

  • Dear Yordan,

    Many Thanks a lot for your guidelines

    1) I will surely follow the references of am335x-evmsk.dts or am335x-evm.dts

    2)Many Thanks a lot for your explanation w.r.t auxclk,  I have doubt ie., What is the frequency of the auxclk is it 26Mhz or 24Mhz, as per TRM it is 26Mhz and as per the below link

    in section Creating pcm5102a_hw_params Function,

    it says sysclock is the clock source that is fed to the McASP internally. It is 24 MHz on all Sitara EVMs.  

    Does sysclock & auxclk are same or different  (terminologies) clocks that is fed to mcasp internally???

    Could you please clarify this doubt w.r.t auxclk,  beacuse my concern is why am not getting accurate 12.288MHZ on scope instead of 12.00Mhz after setting the


        ret = snd_soc_dai_set_clkdiv(cpu_dai, 0, 2);

    And why am not getting accurate 1.536Mhz (48K*16*2) on the scope instead of 1.500Mhz & why am not getting the lrclk as accurate 48Khz on the scope instead of 46.89Khz

    ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);

    I hope beacuse of this am not able to get synchronize the data bits & because of which am not able to get the analog output from the audio codec

    static int evm_uda134x_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 *codec_dai = rtd->codec_dai;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
        struct snd_soc_codec *codec = rtd->codec;
        struct snd_soc_card *soc_card = codec->card;
        int ret = 0;
        unsigned int bclk_freq = evm_get_bclk(params);
        unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
                   snd_soc_card_get_drvdata(soc_card))->sysclk;
        

    #if 1    
        ret = snd_soc_dai_set_clkdiv(cpu_dai, 0, 2);
        if (ret < 0) {
            printk("DAVINCIIIIIIIIII MCLKKK snd_soc_dai_set_clkdiv can't set CPU DAI clock divider %d\n", ret);
            return ret;
        }
    #endif

    #if 1

        ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);
        if (ret < 0) {
            printk("DAVINCIIIIIIIIII BCLKKK can't set CPU DAI clock divider %d\n",
                ret);
            return ret;
        }
    #endif

            /* Set McASP sysclk from AHCLKX sourced from ATL */
        ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
        if (ret < 0)
            dev_err(soc_card->dev, "can't set CPU DAI sysclk %d\n", ret);


        /* Set MCLK as clock source for UDA1345TS ie., set the codec system clock */
        ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT); // SND_SOC_CLOCK_OUT or SND_SOC_CLOCK_IN needs to be rechecked again
        if (ret < 0)
            return ret;

        return 0;

    }


     Kindly do the needful in clarifiying this doubts beacuse if synchronize this mclk, bclk & lrclk correctly w.r.t mcasp, Hope my job would be almost completed

    Kindly do the needful as early as possible

    Awaiting for your replies

    Once thanks a lot for supporting so far Yordan & would appreciate a lot for your prompt responses

  • Hi Srini,

    Srini S said:
    And why am not getting accurate 1.536Mhz (48K*16*2) on the scope instead of 1.500Mhz & why am not getting the lrclk as accurate 48Khz on the scope instead of 46.89Khz

    The following line:
      ret = snd_soc_dai_set_clkdiv(cpu_dai, 0, 2);

    configures the MCLK clock divider to 2, therefore if you've set the sysclk to be the internally generated 24MHz clock (AUXCLK) then you'll get 24/2 = 12MHz master clock on the AHCLKX/ACLKX pin.

    What comes to my mind as a suggestion is:

    Try not to force the MCLK divider to 2, as shown in the example here: http://processors.wiki.ti.com/index.php/Sitara_Linux_SDK_Audio_DAC_Example#Creating_pcm5102a_hw_params_Function

    And use only the BCLK divider:

     

    Srini S said:
    ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);

    This way alsa should automatically adjust according to the bit clock needed when playing specific audio file.


    Best Regards,
    Yordan

  • Thanks a lot Yordan  for your suggestion I tried with 24Mhz only as per your suggestion

    1) I modified my dts for 24Mhz

    ti,codec-clock-rate = <24000000>;

    2) Now am not forcing the  the MCLK divider to 2, and using only the bclk divier as suggested above

    ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);

    3) Am getting the uda134x_hw_params unsupported fs in sound/soc/codecs/uda134x.c because of uda134x->sysclk / params_rate(params) = 24000000 / 48000 = 512, it is entering into default case

        /* set SYSCLK / fs ratio */
        switch (uda134x->sysclk / params_rate(params)) {
        case 512/*500*/:
            printk(KERN_ERR "UDA1345TSSSSSSSSSSSS SYSCLK / fs ratio is 512\n");
            break;
        case 384:
            printk(KERN_ERR "UDA1345TSSSSSSSSSSSS SYSCLK / fs ratio is 384\n");
            hw_params |= (1<<4); // 10000
            break;
        case 256:
            printk(KERN_ERR "UDA1345TSSSSSSSSSSSS SYSCLK / fs ratio is 256\n");
            hw_params |= (1<<5); // 100000
            break;
        default:
            printk(KERN_ERR "%s unsupported fs\n", __func__);
            return -EINVAL;
        }

    Logs:

    _48000Hz_16bit.wav aplay WindowsSoundRecorder_test16_10s_PCM_CBR_1536kbps_Stereo_

    [   79.252374] ENTERED DAVINCI_MCASP_STARTUP FUNCTION!!!!!!!!!!!

    [   79.258530] DAVINCIIIIIIIIII UDA134XXXX evm_startup ENTERED

    Playing WAVE 'WindowsSoundRecorder_test16_10s_PCM_CBR_1536kbps_Stereo_48000Hz_16[   79.271164] DAVINCIIIIIIIIII UDA134XXXX evm_uda134x_hw_para

    bit.wav' : Signed 16 bit Little Endian, Rate 480[   79.282008] DAVINCIIIIIIIIII UDA134XXXXX SYSCLK=24000000

    00 Hz, Stereo

    [   79.291823] DAVINCIIIIIIIIII UDA134XXXXX BCLK FREQQ=1536000

    [   79.299022] DAVINCIIIIIIIIII UDA134XXXXX SYSCLK/BCLK_FREQ =15

    [   79.305137] davinci_mcasp_set_clkdivvvvvvvvvvvvvvvvvv div_id = 1 div = 15

    [   79.312351] uda134x_set_dai_sysclkkkkkkkkkk uda134x_set_dai_sysclk clk_id: 0, freq: 24000000, dir: 1

    [   79.322045] uda134x_set_dai_sysclkkkkkkkkkk uda134x_set_dai_sysclk freq = 24000000 uda134x->sysclk = 24000000

    [   79.332545] UDA1345TSSSSSSSSSSSS RETURN VALUE OF uda134x_read_reg_cache ie., hw_params 0

    [   79.341138] UDA1345TSSSSSSSSSSSS CLOCKS uda134x_hw_params sysclk: 24000000, rate:48000

    [   79.349547] UDA1345TSSSSSSSSSSSS FORMATS uda134x_hw_params dai_fmt: 16385, params_format:2

    [   79.358310] uda134x_hw_params unsupported fs

    [   79.362866] uda134x-codec uda134x.3: ASoC: can't set uda134x-hifi hw params: -22

    aplay: set_params:1166: Unable to install hw params:

    AC[   79.371991] uda134x_muteeeeeeeeee uda134x_mute mute: 1

    CESS:  RW_INTERLEAVED

    FORMAT:  S16_LE

    SUBFORMA[   79.381645] uda134x_write L3 PROTOCOL uda134x_write reg: 0C, value:84

    T:  STD

    SAMPLE_BITS: 16

    FRAME_BITS: 32

    CHANNE[   79.392816] L3 WRITE SUCCESSFULLLLLLL

    LS: 2

    RATE: 48000

    PERIOD_TIME: (42666 42667)

    [   79.400795] uda134x_shutdownnnnnnnnnn

    PERIOD_SIZE: 2048

    PERIOD_BYTES: 8192

    PERIODS: [   79.408878] DAVINCIIIIIIIIII UDA134XXXX evm_shutdown ENETERED

    16

    BUFFER_TIME: (682666 682667)

    BUFFER_SIZE: 32768

    BUFFER_BYTES: 131072

    TICK_TIME: 0

    root@am335x-evm:/#

    Could you please kindly do the needful in suggesting how should I proceeding in resolving this issue further ie., uda134x_hw_params unsupported fs

    Kindly do the needful as early as possible,

    Awaiting for your replies,

    Many Many Thanks a lot for your support once again so far

  • Dear Yordan,

    Could you please provide any inputs in order to resolve the above issue, once again sorry to push you hard


    Thanks in advance again
  • Dear Yordan,

    Could you please provide any inputs in order to resolve the above issue, once again sorry to push you hard


    Thanks in advance again
  • Hi Srini,

    Sorry for the late response.

    As I see, earlier in the thread, I've suggested to set the UDA hw params in davinci-evm.c  by creating  evm_uda134x_hw_params() function. This is adopting the aproach in TI WIKI example.  Having created this function I don't think there is the need of duplicating the hw params function in the UDA134x codec driver (located in sound/soc/codecs.

    What comes to my mind as suggestions:
      1. Having the hw params defined in davinci-evm.c, you can comment the hw_params settings in uda134x.c driver & see what is the result.  Also, this is related to one of your previous quesions, check the aic31xx_audio_map structure in tlv320aic31xx.c  & try to adopt similar audio routing in the UDA134x codec driver.
      OR
     2. Try commenting the evm_uda134x_hw_params() fuction in davinci-evm.c & use only the hw_params settings in the uda134xx.c driver (don't modify the uda134xx.c driver)

    Best Regards,

    Yordan

  • Dear Yordan,

    Thanks a lot for your quick suggestions & responses,

    1) I would like to follow, as per your 1. suggestion i.e, I would like to adopt similar to  aic31xx_audio_map structure in tlv320aic31xx.c in uda134x.c,

    as I was again confused with aic31xx_audio_map structure members,  in my case since am using internal clock source ,whether again I should use CODEC_CLK_IN or CODEC_CLK_OUT???.. & I didn't understand what is PLLCLK, BCLKN_DIV, NDAC_DIV, NADC_DIV, MDAC_DIV &   MADC_DIV?..

    in tlv320aic31xx.c, aic31xx_audio_map structure

        {"CODEC_CLK_IN", NULL, "PLLCLK"},
        {"CODEC_CLK_IN", NULL, "BCLKN_DIV"},
        {"CODEC_CLK_IN", NULL, "NDAC_DIV"},
        {"CODEC_CLK_IN", NULL, "NADC_DIV"},
        {"CODEC_CLK_IN", NULL, "MDAC_DIV"},
        {"CODEC_CLK_IN", NULL, "MADC_DIV"},

        /* Clocks for ADC */
        {"ADC", NULL, "CODEC_CLK_IN"},


        {"ADC", NULL, "MIC_GAIN_CTL"},
        {"MIC_GAIN_CTL", NULL, "Mic Bias"},

        /* Clocks for DAC */
        {"DAC Left", NULL, "CODEC_CLK_IN" },
        {"DAC Right", NULL, "CODEC_CLK_IN"},

        /* Left Output */
        {"Output Left", "From Left DAC", "DAC Left"},
        {"Output Left", "From MIC1LP", "MIC1LP"},
        {"Output Left", "From MIC1RP", "MIC1RP"},

        /* Right Output */
        {"Output Right", "From Right DAC", "DAC Right"},
        {"Output Right", "From MIC1RP", "MIC1RP"},


        {"ADC", NULL, "MIC_GAIN_CTL"},
        {"MIC_GAIN_CTL", NULL, "Mic Bias"},

        /* Clocks for DAC */
        {"DAC Left", NULL, "CODEC_CLK_IN" },
        {"DAC Right", NULL, "CODEC_CLK_IN"},

        /* Left Output */
        {"Output Left", "From Left DAC", "DAC Left"},
        {"Output Left", "From MIC1LP", "MIC1LP"},
        {"Output Left", "From MIC1RP", "MIC1RP"},

        /* Right Output */
        {"Output Right", "From Right DAC", "DAC Right"},
        {"Output Right", "From MIC1RP", "MIC1RP"},

    2) How mclk, bit clock & lrclk mapping from mcasp to codec is done in this structure???

    3) as am new to alsa, as am using uda1345TS chipset (datasheet - UDA1345TS), as of now I have changed the routing particularly according to uda1345ts instead of uda134x, could you please help me in creating the structure the similar to Could you please help me in creating uda134x_audio_map structure similar to aic31xx_audio_map

    In sound/soc/codecs/uda134x.c

    /* Common DAPM widgets */

    static const struct snd_soc_dapm_widget uda134x_dapm_widgets[] = {

    //SND_SOC_DAPM_INPUT("VINL1"),

    //SND_SOC_DAPM_INPUT("VINR1"),

    //SND_SOC_DAPM_INPUT("VINL2"),

    //SND_SOC_DAPM_INPUT("VINR2"),

    SND_SOC_DAPM_INPUT("VINL"),

    SND_SOC_DAPM_INPUT("VINR"),

    SND_SOC_DAPM_OUTPUT("VOUTL"),

    SND_SOC_DAPM_OUTPUT("VOUTR"),

    };

    static const struct snd_soc_dapm_route uda134x_dapm_routes[] = {

    //{ "ADC", NULL, "VINL1" },

    //{ "ADC", NULL, "VINR1" },

    //{ "ADC", NULL, "VINL2" },

    //{ "ADC", NULL, "VINR2" },

    { "ADC", NULL, "VINL" },

    { "ADC", NULL, "VINR" },

    { "VOUTL", NULL, "DAC" },

    { "VOUTR", NULL, "DAC" },

    };

    In DTSI

                          ti,audio-routing =

    "ADC",       "VINL",

    "ADC",       "VINR",

    "VOUTL",               "DAC",

    "VOUTR",               "DAC";

    In davinci-evm.c

    static int evm_uda134x_init(struct snd_soc_pcm_runtime *rtd)

    {

    struct snd_soc_codec *codec = rtd->codec;

    struct snd_soc_dapm_context *dapm = &codec->dapm;

    struct device_node *np = codec->card->dev->of_node;

    int ret;

    printk("DAVINCIIIIIIIIIII UDA134XXXXX  evm_uda134x_init ENTERED\n");

    snd_soc_dapm_new_controls(dapm, uda134x_dapm_widgets,

     ARRAY_SIZE(uda134x_dapm_widgets));

    if (np) {

    ret = snd_soc_of_parse_audio_routing(codec->card,

        "ti,audio-routing");

    if (ret)

    {

    printk("DAVINCIIIIIIIIIII UDA134XXXXX  DAPM ROUTING BASED ON DTS IS FAILURE\n");

    return ret;

    }

    else

    {

    printk("DAVINCIIIIIIIIIII UDA134XXXXX  DAPM ROUTING BASED ON DTS IS SUCCESSFULL\n");

    }

    } else {

    /* Set up davinci-evm specific audio path audio_map */

    printk("DAVINCIIIIIIIIIII UDA134XXXXX  DAPM ROUTING\n");

    snd_soc_dapm_add_routes(dapm, uda134x_dapm_routes, ARRAY_SIZE(uda134x_dapm_routes));

    }

    //snd_soc_dapm_enable_pin(dapm, "VINL1"),

    //snd_soc_dapm_enable_pin(dapm, "VINR1"),

    //snd_soc_dapm_enable_pin(dapm, "VINL2"),

    //snd_soc_dapm_enable_pin(dapm, "VINR2"),

    snd_soc_dapm_enable_pin(dapm, "VINL"),

    snd_soc_dapm_enable_pin(dapm, "VINR"),

    snd_soc_dapm_enable_pin(dapm, "VOUTL");

    snd_soc_dapm_enable_pin(dapm, "VOUTR");

    return 0;

    }

    I hope this should resolve all my problems Yordan, & would appreciate a lot once again for providing since long term support w.r.t this thread


    Could you please help me in creating this uda134x_audio_map structure as it is simple, because I don't know how mclk, bitclk & lrclk binding of mcasp with codec is done in this structure


    Would be very grateful to you.. Yordan, please help me in creating this structure as early as possible

    Awaiting for you replies

    Many Thanks in advance Yordan once again

  • Dear Yordan

    1. Could you please help me in creating this structure uda134x_audio_map , as early as possible

    2. Could you please finally confirm that whether mclk ie., ahclkx , if we are using internal clock source is it possible to achieve,

    Mclk = 256 * 48Khz = 12288000Hz or 384*48Khz = 18432000Hz or 512*48Khz = 24576000 Hz accurately or not, if we are using internal clock source (ie., what are all the divider value that needs to be used for 24Mhz inorder to get 12288000Hz (as of now am getting 12Mhz, but what is the divider that needs to be used to get 18432000Hz or24576000 Hz ) for programming in AHCLKX register

    Awaiting for your replies,

    Many Thanks in advance,
  • Dear Yordan,

    Please provide any inputs w.r.t the above queries, as early as possible, as its from long time,

    And am stuck with this from last week & unable to proceed further

    Kindly do the needful as early as possible

    Awaiting for your replies,
  • Hi,

    Srini S said:
    Could you please help me in creating this structure uda134x_audio_map , as early as possible

    The audio map structure should describe what is connected to your codec/am335x device, i.e. left/right channel of the mic, input/output channel and so on. That depends on how your hardware is connected.

    As for the second question, as I said ALSA should calculate the needed clock dividers, based on the input audio file.  If you check Figure 22-1. McASP Block Diagram you will see that the output clocks from the MCASP interface (ACLK & AHCLK) to the audio codec, are directly derived from the corresponding clock divider (see MCASP Register Manual). So the value that should be written in AHCLK div, if,  for example,12.228Mhz clock is needed would be 24/12.288.

    However I am not that experienced in writing audio codec drivers, so maybe someone else should elaborate here.

    Best Regards,

    Yordan

  • Thanks a lot for your support & suggestions Yordan

    Could anybody kindly requesting any TI audio codec drivers expert to support for the above issues

    Kindly do the needful as early as possible
  • Dear Yordan,

    Could you please suggest any TI AUDIO CODEC driver experts for the above issue

    Please do the needful

    Thanks in advance
  • Dear Yordan,

    Finally the great day has come!!! Finally I was able to get my UDA134x Audio codec playback initially up & running with mcasp

    Many Thanks a lot Yordan, for your prompt support & efforts in guiding me & suggestions & would appreciate a lot for your quick & timely responses

    It was really great breakthrough!!!

    Many Many Thanks Yordan once again
  • Hi Srini,

    I am glad to hear that.

    Best Regards,
    Yordan
  • Dear Yordan,

    You are Most Welcome!!

    Thanks & regards,
    Srini