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.

MCASP as slave with dummy I2S codec as master

Hi, I'm working on an am335x project and I am trying to integrate an audio capture-only codec that acts as I2S master and produces sound in LEFT-J format. This codec has no audio controls over i2c. I've set up a dummy codec module that just accepts any parameter and is fixed to 16KHz, 16-bit LE, stereo audio. I've hooked that up to the davinci-evm module and added this DAI:

static struct snd_soc_dai_link input_dai_dummy_i2s = {            
    .name       = "Dummy I2S Capture",
    .stream_name    = "Capture",
    .codec_dai_name = "dummy-i2s",
    .ops            = &evm_ops,
    .init           = evm_dummy_i2s_init,
    .dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_NB_NF,
};

And I've updated the device tree IDs for my new codec:

static const struct of_device_id davinci_evm_dt_ids[] = {
    {
        .compatible = "ti,dummy-i2s-evm-audio",
        .data = (void *) &input_dai_dummy_i2s,
    },
    {
        .compatible = "ti,da830-evm-audio",
        .data = (void *) &evm_dai_tlv320aic3x,
    },
    { /* sentinel */ }
}

My evm_dummy_i2s_init is almost the same as the evm_aic3x_init function except I've removed the controls and non-connected pin registration:

static int evm_dummy_i2s_init(struct snd_soc_pcm_runtime *rtd)                
{                                                                         
    struct snd_soc_card *card = rtd->card;                                
    struct snd_soc_codec *codec = rtd->codec;                             
    struct device_node *np = card->dev->of_node;                          
    int ret;                                                              
                                                                          
    if (np) {                                                             
        ret = snd_soc_of_parse_audio_routing(card, "ti,audio-routing");   
        if (ret)                                                          
            return ret;                                                   
    } else {                                                              
        /* Set up davinci-evm specific audio path audio_map */            
        snd_soc_dapm_add_routes(&card->dapm, audio_map,                   
                    ARRAY_SIZE(audio_map));                               
    }
                                                                          
    return 0;                                                             
}                                                                         

Finally, I added some device tree nodes (in this reduced example I'm working on a beaglebone black) and removed all the HDMI connectivity. I also enabled mcasp in mode 3 so I can use P8's pins 33, 35, and 36.

/*
 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
/dts-v1/;

#include "am33xx.dtsi"
#include "am335x-bone-common.dtsi"

/ {
	model = "TI AM335x BeagleBone Black";
	compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";
};

&ldo3_reg {
	regulator-min-microvolt = <1800000>;
	regulator-max-microvolt = <1800000>;
	regulator-always-on;
};

&mmc1 {
	vmmc-supply = <&vmmcsd_fixed>;
};

&mmc2 {
	vmmc-supply = <&vmmcsd_fixed>;
	pinctrl-names = "default";
	pinctrl-0 = <&emmc_pins>;
	bus-width = <8>;
	status = "okay";
};

&rtc {
	system-power-controller;
};

&am33xx_pinmux {

	mcasp0_audio_input_pins: mcasp0_audio_input_pins {
		pinctrl-single,pins = <
			0xd0 ( PIN_INPUT | MUX_MODE3 ) /* (V2) lcd_data12.mcasp0_aclkr */
			0xd4 ( PIN_INPUT | MUX_MODE3 ) /* (V3) lcd_data13.mcasp0_fsr */
			0xc8 ( PIN_INPUT | MUX_MODE3 ) /* (U3) lcd_data10.mcasp0_axr0 */
		>;
	};

	mcasp0_audio_input_pins_sleep: mcasp0_audio_input_pins_sleep {
		pinctrl-single,pins = <
			0xd0 ( PIN_INPUT | MUX_MODE3 ) /* (V2) lcd_data12.mcasp0_aclkr */
			0xd4 ( PIN_INPUT | MUX_MODE3 ) /* (V3) lcd_data13.mcasp0_fsr */
			0xc8 ( PIN_INPUT | MUX_MODE3 ) /* (U3) lcd_data10.mcasp0_axr0 */
		>;
	};

};

&mcasp0 {

    pinctrl-names = "default", "sleep";
    pinctrl-0 = <&mcasp0_audio_input_pins>;
    pinctrl-1 = <&mcasp0_audio_input_pins_sleep>;

    status = "okay";
    op-mode = <0>;
    tdm-slots = <2>;
    serial-dir = <
        2 0 0 0
    >;
    rx-num-evt = <1>;
    tx-num-evt = <1>;
};

/ {

	dummy_i2s: dummy_i2s {
		compatible = "linux,dummy-i2s";
		status = "okay";
	};

	sound@0 {
		compatible = "ti,dummy-i2s-evm-audio";
		ti,model = "Dummy I2S";
		ti,audio-codec = <&dummy_i2s>;
		ti,mcasp-controller = <&mcasp0>;
		ti,codec-clock-rate = <1024000>;
		ti,audio-routing = "ANA IN1", "Internal Mic";
	};

};

Anyway, I'm running Linux 4.4.1 and the codec registers correctly after all this. However, when I try to record with arecord, it hangs indefinitely and no audio is produced to the output file. I can verify that the device is producing a 1024000 Hz bit clock and 16000 Hz frame sync clock. I have a 3-wire connection between the codec and my beaglebone with ACLKR, FSR, and AXR0 pins hooked up.

A representative from the codec maker has indicated that the codec does not need a master clock but maybe the mcasp/davinci-evm needs one when operating as slave. Does anyone have any experience in these cases?

Thanks.