AnsweredAssumed Answered

Question about audio record with ssi as i2s slave

Question asked by li weihua on May 18, 2018
Latest reply on Oct 9, 2018 by Jun Huang

Hello guys,

We are try to perform audio record function on imx6q platform.

The hardware design is as follows:

1. The analog voice signal comes into TEF6638 from AIN0 and digital I2S signal output from HOST_O_SD0,TEF6638 provides bit clock and word select signal through HOST_BCK and HOST_WS

2. In the i.MX6  side,ssi1 and AUD3 is used to receive I2S clock and data from TEF6638

3.The I2C reg configurations of TEF6638 are all done in MCU side, and i.MX6 is only responsible for codec.

My configurations of i.MX6 side are:

1.device tree:

tef6638_codec: tef6638-codec {                                      
                compatible = "tef6638-codec";                               
                //clocks = <&clks IMX6QDL_CLK_CKO>;                              
        };

sound-tef6638 {                                                     
                compatible = "fsl,imx-audio-tef6638";                       
                model = "imx-tef6638";                                      
                ssi-controller = <&ssi1>;                                   
                audio-codec = <&tef6638_codec>;                             
                mux-int-port = <1>;                                         
                mux-ext-port = <3>;                                         
        };

&ssi1 {                                                                     
        fsl,mode = "i2s-slave";                                             
        status = "okay";                                                    
};

2.AUDMUX

static int imx_audmux_config(int slave, int master)                         
{                                                                           
    unsigned int ptcr, pdcr;                                                
    /*                                                                      
     * The port numbering in the hardware manual starts at 1, while         
     * the audmux API expects it starts at 0.                               
     */                                                                     
     slave = slave - 1;                                                     
     master = master - 1;                                                   
                                                                            
     ptcr = IMX_AUDMUX_V2_PTCR_SYN |                                        
            IMX_AUDMUX_V2_PTCR_TFSDIR |                                     
            IMX_AUDMUX_V2_PTCR_TFSEL(master) |                              
            IMX_AUDMUX_V2_PTCR_TCLKDIR |                                    
            IMX_AUDMUX_V2_PTCR_TCSEL(master);                               
     pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(master);                              
     imx_audmux_v2_configure_port(slave, ptcr, pdcr);                       
                                                                            
     ptcr = IMX_AUDMUX_V2_PTCR_SYN;                                         
     pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(slave);                               
     imx_audmux_v2_configure_port(master, ptcr, pdcr);                      
                                                                            
     return 0;                                                              
}

3.hw params:

static int imx_tef6638_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)          {                                                                           
    struct snd_soc_pcm_runtime *rtd = substream->private_data;              
    struct snd_soc_dai *cpu_dai = rtd->cpu_dai;                             
    struct snd_soc_dai *codec_dai = rtd->codec_dai;                         
    unsigned int channels = params_channels(params);                        
    int ret = 0;                                                            
    u32 dai_format;                                                         

                                                                                  
    dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LSB | SND_SOC_DAIFMT_NB_NF |
                 SND_SOC_DAIFMT_CBM_CFM;                                    
                                                                            
    /* set cpu DAI configuration */                                         
    ret = snd_soc_dai_set_fmt(cpu_dai, dai_format);                         
    if (ret < 0) {                                                          
        printk("imx_tef6638_hw_params: snd_soc_dai_set_fmt error!\n");
        return ret;                                                         
    }                                                                       
                                                                            
    /* set i.MX active slot mask */                                         
    snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, 32);                                     
                                                                                                
    /* set the SSI system clock as input */                                 
    snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_IN);          
           
    snd_soc_dai_set_sysclk(codec_dai, 0, clk_frequency, SND_SOC_CLOCK_OUT);
                                                                            
    return 0;                                                               
}

4.static struct snd_soc_dai_driver tef6638_codec_dai = {                      
        .name = "tef6638",                                                  
        .playback = {                                                       
        .stream_name = "playback",                                          
        .channels_min = 1,                                                  
        .channels_max = 2,                                                  
        .rates = SNDRV_PCM_RATE_44100,                                             
        .formats = SNDRV_PCM_FMTBIT_S16_LE,                                         
    },                                                                      
        .capture = {                                                        
        .stream_name = "capture",                                           
        .channels_min = 1,                                                  
        .channels_max = 2,                                                  
        .rates = SNDRV_PCM_RATE_44100,                                             
        .formats = SNDRV_PCM_FMTBIT_S16_LE,                                         
    },                                                                      
};

Now,the sound card is precented:

##arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: imxtef6638ssi [imx-tef6638-ssi], device 0: imx-tef6638 tef6638-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

 

but when I start record with command:

##arecord -Dplughw:0,0 -c 2 -r 44100 -f S16_LE -d 5 /tmp/record.wav,

I get a error :

arecord: pcm_read:1828: read error: Input/output error

 

Could anyone tell me how to config the clocks of the codec dai?

 

Best regards.

LevisLi

Outcomes