linux/sound/soc/ux500/ux500_pcm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) ST-Ericsson SA 2012
   4 *
   5 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
   6 *         Roger Nilsson <roger.xr.nilsson@stericsson.com>
   7 *         for ST-Ericsson.
   8 */
   9
  10#include <asm/page.h>
  11
  12#include <linux/module.h>
  13#include <linux/dma-mapping.h>
  14#include <linux/dmaengine.h>
  15#include <linux/slab.h>
  16
  17#include <sound/pcm.h>
  18#include <sound/pcm_params.h>
  19#include <sound/soc.h>
  20#include <sound/dmaengine_pcm.h>
  21
  22#include "ux500_msp_i2s.h"
  23#include "ux500_pcm.h"
  24
  25#define UX500_PLATFORM_PERIODS_BYTES_MIN        128
  26#define UX500_PLATFORM_PERIODS_BYTES_MAX        (64 * PAGE_SIZE)
  27#define UX500_PLATFORM_PERIODS_MIN              2
  28#define UX500_PLATFORM_PERIODS_MAX              48
  29#define UX500_PLATFORM_BUFFER_BYTES_MAX         (2048 * PAGE_SIZE)
  30
  31static int ux500_pcm_prepare_slave_config(struct snd_pcm_substream *substream,
  32                struct snd_pcm_hw_params *params,
  33                struct dma_slave_config *slave_config)
  34{
  35        struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
  36        struct snd_dmaengine_dai_dma_data *snd_dma_params;
  37        dma_addr_t dma_addr;
  38        int ret;
  39
  40        snd_dma_params = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0), substream);
  41        dma_addr = snd_dma_params->addr;
  42
  43        ret = snd_hwparams_to_dma_slave_config(substream, params, slave_config);
  44        if (ret)
  45                return ret;
  46
  47        slave_config->dst_maxburst = 4;
  48        slave_config->src_maxburst = 4;
  49
  50        slave_config->src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
  51        slave_config->dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
  52
  53        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  54                slave_config->dst_addr = dma_addr;
  55        else
  56                slave_config->src_addr = dma_addr;
  57
  58        return 0;
  59}
  60
  61static const struct snd_dmaengine_pcm_config ux500_dmaengine_of_pcm_config = {
  62        .prepare_slave_config = ux500_pcm_prepare_slave_config,
  63};
  64
  65int ux500_pcm_register_platform(struct platform_device *pdev)
  66{
  67        int ret;
  68
  69        ret = snd_dmaengine_pcm_register(&pdev->dev,
  70                                         &ux500_dmaengine_of_pcm_config, 0);
  71        if (ret < 0) {
  72                dev_err(&pdev->dev,
  73                        "%s: ERROR: Failed to register platform '%s' (%d)!\n",
  74                        __func__, pdev->name, ret);
  75                return ret;
  76        }
  77
  78        return 0;
  79}
  80EXPORT_SYMBOL_GPL(ux500_pcm_register_platform);
  81
  82int ux500_pcm_unregister_platform(struct platform_device *pdev)
  83{
  84        snd_dmaengine_pcm_unregister(&pdev->dev);
  85        return 0;
  86}
  87EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform);
  88
  89MODULE_AUTHOR("Ola Lilja");
  90MODULE_AUTHOR("Roger Nilsson");
  91MODULE_DESCRIPTION("ASoC UX500 driver");
  92MODULE_LICENSE("GPL v2");
  93