Quantcast
Channel: Forums - Recent Threads
Viewing all articles
Browse latest Browse all 262198

Linux/AM3352: MCASP read error

$
0
0

Part Number:AM3352

Tool/software: Linux

Hi.

I am trying to read MCASP using ALSA library. 

I found read error message. "arecord: pcm_read:2032: read error: Input/output error"

please check my system.

 

- I2S format

AM3352 receive I2S data and clock from Bluetooth module.

I2S bit format is 32bit slot size, 24bit word and Left justified.

- Kernel device driver (4.4.32 version)

I can not understand to config slot size as 32bit. So I attached "mcasp->slot_width = 32;" in davinci-mcasp.c. Is this OK?

Also I am not sure MCASP slave configuration. Please check my clock configuration in davinci-evm.c

davinci-evm.c

static int pcm5102a_capture_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_card *soc_card = rtd->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("[kdj6724] %s(%d) codec_dai:%s cup_dai:%s", __FUNCTION__, __LINE__, codec_dai->name, cpu_dai->name);
  /* set the codec system clock */
    ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);
  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;

  //ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xFFFFFF, 0xFFFFFF, 2, 32);
  //if (ret < 0)
//    return ret;

  return 0;
}

// kdj6724
static struct snd_soc_ops pcm5102a_capture_ops = {
    .startup = evm_startup,
    .shutdown = evm_shutdown,
    .hw_params = pcm5102a_capture_hw_params,
    //.hw_params = pcm5102a_playback_hw_params,
};

static struct snd_soc_dai_link evm_dai_pcm5102a_in = { 
    .name       = "PCM5102A", //This is chosen arbitrarily.  Can be anything.
    .stream_name    = "Capture", //This comes from the PCM5102a driver create previously.
    .codec_dai_name = "pcm5102a-hifi", //This comes from the PCM5102a driver create previously
    .ops            = &pcm5102a_capture_ops, //This is a structure that we will create later.
    //.ops            = &pcm5102a_playback_ops, //This is a structure that we will create later.
    .dai_fmt    = (SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_LEFT_J |
               SND_SOC_DAIFMT_IB_NF),
};

davinci-mcasp.c
static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
               int sample_width)
{
  u32 fmt; 
  u32 tx_rotate = (sample_width / 4) & 0x7; 
  u32 mask = (1ULL << sample_width) - 1; 
  u32 slot_width = sample_width;

  /*
   * For captured data we should not rotate, inversion and masking is
   * enoguh to get the data to the right position:
   * Format   data from bus   after reverse (XRBUF)
   * S16_LE:  |LSB|MSB|xxx|xxx| |xxx|xxx|MSB|LSB|
   * S24_3LE: |LSB|DAT|MSB|xxx| |xxx|MSB|DAT|LSB|
   * S24_LE:  |LSB|DAT|MSB|xxx| |xxx|MSB|DAT|LSB|
   * S32_LE:  |LSB|DAT|DAT|MSB| |MSB|DAT|DAT|LSB|
   */
  u32 rx_rotate = 0; 

  /*
   * Setting the tdm slot width either with set_clkdiv() or
   * set_tdm_slot() allows us to for example send 32 bits per
   * channel to the codec, while only 16 of them carry audio
   * payload.
   */
  // kdj6724 add
  mcasp->slot_width = 32;
  if (mcasp->slot_width) {
    /*   
     * When we have more bclk then it is needed for the
     * data, we need to use the rotation to move the
     * received samples to have correct alignment.
     */
    slot_width = mcasp->slot_width;
    rx_rotate = (slot_width - sample_width) / 4; 
  }

  /* mapping of the XSSZ bit-field as described in the datasheet */
  fmt = (slot_width >> 1) - 1; 

  if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) {
        printk("[kdj6724] %s(%d)", __FUNCTION__, __LINE__);
    mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt),
             RXSSZ(0x0F));
    mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXSSZ(fmt),
             TXSSZ(0x0F));
    mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, TXROT(tx_rotate),
             TXROT(7));
    mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXROT(rx_rotate),
             RXROT(7));
    mcasp_set_reg(mcasp, DAVINCI_MCASP_RXMASK_REG, mask);
  }
   mcasp_set_reg(mcasp, DAVINCI_MCASP_TXMASK_REG, mask);

    mcasp_reg_dump(mcasp);
  return 0;
}


Viewing all articles
Browse latest Browse all 262198

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>