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.

How to setup DM8168 DVR 24bit audio encode support?

Other Parts Discussed in Thread: PCM1803A, PCM1803, TVP5158

Hi,

I meet the same problem with the person in

http://e2e.ti.com/support/embedded/linux/f/354/t/58191.aspx

I'm using DM8168 DVR 4.0. The decoder is PCM1803A. It is a 24bit audo codec.

I'm thinking these files:

/ti_tools/linux_lsp/kernel/linux-dvr-rdk/arch/arm/mach-omap2/devices.c

/ti_tools/linux_lsp/kernel/linux-dvr-rdk/sound/soc/davinci/davinci-mcasp.c

/ti_tools/linux_lsp/kernel/linux-dvr-rdk/sound/soc/davinci/davinci-pcm.c

should be modified. Can you tell me how to do that?

 

  • Hi,

    What value should be seup in Table 14-23. Receive Bit Stream Format Register (RFMT)  if using I2S interface with 24bit word length?

  • For this same question, we are using DVRRDK4.0 with PCM1803 24 bit. Since PCM1803 does not need any codec side configuration, we just re-use the tvp5158-audio driver. Below is our code:

    In /ti_tools/linux_lsp/kernel/linux-dvr-rdk/arch/arm/mach-omap2/devices.c:

    static struct snd_platform_data tvp5158_snd_data = {
    .tx_dma_offset = 0x46000000,
    .rx_dma_offset = 0x46000000,
    .asp_chan_q = EVENTQ_0,
    .tdm_slots = 2,// PCM1803 use 2 for I2S. /* number of channels */
    // .tdm_slots = 16, /* number of channels */
    .op_mode = DAVINCI_MCASP_IIS_MODE,
    .num_serializer = ARRAY_SIZE(tvp5158_iis_serializer_direction),
    .serial_dir = tvp5158_iis_serializer_direction,
    .version = MCASP_VERSION_2,
    .txnumevt = 0, // PCM1803 
    .rxnumevt = 1, // PCM1803 
    /* PCM1803 need to feed CODEC CLK*/
    .clk_input_pin = MCASP_AHCLKX_OUT,
    };

    In /ti_tools/linux_lsp/kernel/linux-dvr-rdk/sound/soc/davinci/davinci-mcasp.c

    function davinci_mcasp_probe(struct platform_device *pdev): here we added the clock for PCM1803:

    if (pdev->id == 0)
    clk_set_rate(dev->clk, 24576000);

    if (pdev->id == 0)
    mcasp_ahclkx_enable(dev);

    In static struct snd_soc_dai_driver davinci_mcasp_dai[] = {

    {
    .name = "davinci-mcasp.0",
    .capture = {
    .channels_min = 2,

    .channels_max = 2,
    .rates = DAVINCI_MCASP_RATES,
    .formats = SNDRV_PCM_FMTBIT_S8 |
    SNDRV_PCM_FMTBIT_S16_LE |
    SNDRV_PCM_FMTBIT_S24_LE | // PCM1803 use 24 bit
    SNDRV_PCM_FMTBIT_S32_LE,
    },
    .ops = &davinci_mcasp_dai_ops,

    },

    In the we setting the cpu-dai register for 24 bit(32bit rotate 8):

    static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
    struct snd_pcm_hw_params *params,
    struct snd_soc_dai *cpu_dai)

    {

    int word_length;
    u8 fifo_level;

    davinci_hw_common_param(dev, substream->stream);
    if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
    fifo_level = dev->txnumevt;
    else
    fifo_level = dev->rxnumevt;

    davinci_hw_param(dev, substream->stream);

    switch (params_format(params)) {
    case SNDRV_PCM_FORMAT_S8:
    dma_params->data_type = 1;
    word_length = DAVINCI_AUDIO_WORD_8;
    break;

    case SNDRV_PCM_FORMAT_S16_LE:
    dma_params->data_type = 2;
    word_length = DAVINCI_AUDIO_WORD_16;
    break;
    case SNDRV_PCM_FORMAT_S32_LE:
    dma_params->data_type = 4;
    word_length = DAVINCI_AUDIO_WORD_32;
    break;

    default:
    printk(KERN_WARNING "davinci-mcasp: unsupported PCM format");
    return -EINVAL;
    }

    if (dev->version == MCASP_VERSION_2 && !fifo_level)
    dma_params->acnt = 4;
    else
    dma_params->acnt = dma_params->data_type;

    dma_params->fifo_level = fifo_level;
    davinci_config_channel_size(dev, word_length);

    mcasp_set_reg(dev->base + DAVINCI_MCASP_RXFMT_REG, 0x000180F6); //PCM1803

    }

    In function davinci_hw_param(): we does not change any code.

    In function davinci_config_channel_size(): we does not change any code.

    In file /ti_tools/linux_lsp/kernel/linux-dvr-rdk/sound/soc/davinci/davinci-pcm.c

    we set to support format S24_LE

    static struct snd_pcm_hardware pcm_hardware_playback = {
    .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
    SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
    SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
    // .formats = (SNDRV_PCM_FMTBIT_S16_LE),//  PCM1803 use 24 bit
    .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE| SNDRV_PCM_FMTBIT_S32_LE),
    .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
    SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
    SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
    SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
    SNDRV_PCM_RATE_KNOT),
    .rate_min = 8000,
    .rate_max = 96000,
    .channels_min = 2,
    .channels_max = 2,
    .buffer_bytes_max = 128 * 1024,
    .period_bytes_min = 32,
    .period_bytes_max = 16 * 1024,
    .periods_min = 2,
    .periods_max = 255,
    .fifo_size = 0,
    };

    static struct snd_pcm_hardware pcm_hardware_capture = {
    .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
    SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
    SNDRV_PCM_INFO_PAUSE),
    // .formats = (SNDRV_PCM_FMTBIT_S16_LE),//  PCM1803 use 24 bit
    // .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE),
    .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE| SNDRV_PCM_FMTBIT_S32_LE),
    .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
    SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
    SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
    SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
    SNDRV_PCM_RATE_KNOT),
    .rate_min = 8000,
    .rate_max = 96000,
    .channels_min = 2,
    .channels_max = 2,
    .buffer_bytes_max = 128 * 1024,
    .period_bytes_min = 32,
    .period_bytes_max = 16 * 1024,
    .periods_min = 2,
    .periods_max = 255,
    .fifo_size = 0,
    };

    Finally we change the code of /ti_tools/linux_lsp/kernel/linux-dvr-rdk/sound/soc/davinci/ti81xx-evm.c

    static int ti81xx_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;
    unsigned sysclk, fmt = 0;

    /* default */
    sysclk = 24576000;

    if (!strcmp(rtd->dai_link->name, "TVP5158AUDIO")) {
    /********** begin PCM1803: when use I2S, the fmt must be NB_IF, not IB_NF **************/
    /* 5158 use DSPA, 1803 use either DSPA or I2S */
    fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM |
    SND_SOC_DAIFMT_NB_IF;
    /********** end PCM1803: when use I2S, the fmt must be NB_IF, not IB_NF **************/
    } else {
    /*
    * DSP_B Mode
    */
    fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM |
    SND_SOC_DAIFMT_IB_NF;
    }

    /* set codec DAI configuration */
    snd_soc_dai_set_fmt(codec_dai, fmt);
    /* set cpu DAI configuration */
    snd_soc_dai_set_fmt(cpu_dai, fmt);
    /* set the codec system clock */
    snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT);

    return 0;
    };

     

    Now the strange thing is, if we use arecord -D hw:0.1, this is for AIC3101, it will show S16_LE and S32_LE available. But if we use arecord -D hw:0.0, for the PCM1803, it will only show S16_LE avalable. WHY no S32_LE and S24_LE acceptable?

    We even re-compile the source code of arecord, and found that after calling ALSA API snd_pcm_hw_params_any(), the format will be set to only S16_LE for hw0.0 and S16/S24 for hw0.1 .

    Could anyone help us explain why?

    thanks a lot in advance!

  • Can TI experts reply? This problem baffled us quite along time. DVR 4.0 only supports 16bit for McASP0, and 16bit/32bit for McASP1. But I'm using 24bit Audio codec. I don't want my board wasted.

    Any assistance will be appreciated.