[alsa-devel] [PATCH 00/17] ASoC: Towards a generic dmaengine PCM driver

Lars-Peter Clausen lars at metafoo.de
Mon Apr 15 19:19:47 CEST 2013


This series adds a (almost) generic dmaengine PCM driver for ASoC. The tegra,
spear, omap, imx, mxs, ep93xx and ux500 platforms are converted to use the
generic driver instead of their own custom implementation. The driver builds on
top of the dmaengine PCM library and adds the missing bits. The driver was
primarily built for handling devicetree based platforms, but the series also
adds support for compat platforms which don't use devicetree yet or have to
support non-devicetree instantiation for backwards compatibility. Since non of
the converted platforms have devicetree support yet (at least not using the
generic DMA bindings) this series doesn't enable devicetree support for them
either.  But enabling support for them is very easy and can be done by removing
the SND_DMAENGINE_PCM_NO_DT flag for these platforms.

For platforms using devicetree the DMA channels are requested early on before
the ASoC platform driver is registered. This allows us, at least in theory, to
use probe deferral if the DMA driver hasn't been probed yet. Unfortunately
of_dma_request_slave_channel either returns a valid channel or NULL, so we can't
distinguish between the case where there is no DMA channel assigned and the case
where the DMA driver hasn't been probed yet. I plan to submit a patch which lets
of_dma_request_slave_channel return a ERR_PTR, but for now the generic PCM
dmaengine driver assumes that the DMA driver will always be probed before it.
For the compat case the DMA channel gets requested from within the PCM driver's
pcm_new callback. This requires some minor changes to some of the DAI drivers
moving the initialization of the DAI DMA data pointer from the DAI startup
callback to the DAI probe callback.

Unfortunately the driver is not fully generic yet and we still need some
platform specific data to make it work, but the plan is to eventually make the
driver fully generic in the future. The platform specific bits currently are:
 * The snd_pcm_hardware struct which contains device specific parameters like
   the maximum period size and maximum number of periods as well as whether the
   driver supports pause and resume. The idea is to get rid of the per platform
   snd_pcm_hardware struct by extending the dmaengine API to a point where we
   can query all necessary information from the dmaengine driver to fill in the
   snd_pcm_hardware struct at runtime.
 * The size of the pre-allocated audio buffer. All platforms seem use different
   sizes and since some of them might be sensitive to changes to the buffer
   size this series keeps the original size for now. But we should probably try
   to decide on a sane default for this and maybe allow ASoC board drivers to
   overwrite it somehow.
 * A callback to fill in the dma_slave_config. Currently this is either NULL
   (for platforms which don't need to configure the DMA channel at runtime) or
   uses the generic snd_dmaengine_pcm_prepare_slave_config(), which uses
   snd_hwparams_to_dma_slave_config() and snd_dmaengine_pcm_set_config_from_dai_data().
   The later requires the platform to use the generic DMA DAI data struct
   though, hopefully we'll be able to convert all platforms to use this generic
   struct, and once that's done we can always use
   snd_dmaengine_pcm_prepare_slave_config() unconditionally.
 * For platforms not using devicetree platforms a callback to request the dma
   channel. This can either be a completely custom function which returns the
   channel or a filter function which will be passed to dma_request_channel. 
   The route forward here probably is to let the DAI driver provide the filter
   function or implement a table based DMA channel lookup like we have for other
   subsystems (like clk or regulator) where the board file provides a mapping
   based on the device name.

Platforms which use the dmaengine pcm library but are not converted to the
generic driver yet are atmel and mmp. mmp use a custom genalloc based memory
allocator, we may add support for this to the generic driver at a later point.
The atmel PCM driver is very interlocked with atmel SSC DAI driver, it'll
probably require some serious refactoring before it can use the generic
dmaengine PCM driver.

The driver uses snd_pcm_lib_preallocate_pages to preallocate the memory buffer.
snd_pcm_lib_preallocate_pages internally uses dma_alloc_coherent, while most of
the platforms converted in this series use dma_alloc_writecombine. Laxman
Dewangan submitted a patch[1] a couple of months ago to add support for
dma_alloc_writecombine to snd_pcm_lib_preallocate_pages, I always thought the
patch had been merged, but it looks like I was mistaken. So if there are
concerns about performance regression due to using coherent instead of
writecombine mappings we'll have to postpone converting these platforms until
Laxman's patch has been merged.

The compat path of this series hasn't been runtime tested yet and neither have
the platforms which are converted in this series. I probably broke one or two of
them by accident, so please test the patches.

- Lars

[1] https://lkml.org/lkml/2012/7/2/94

Lars-Peter Clausen (17):
  ASoC: dmaengine-pcm: Make requesting the DMA channel at PCM open
  ASoC: Add snd_soc_{add,remove}_platform
  ASoC: Add a generic dmaengine_pcm driver
  ASoC: dmaengine_pcm: Add support for compat platforms
  ASoC: tegra: Use generic dmaengine PCM
  ASoC: spear: Setup dma data in DAI probe
  ASoC: spear: Use generic dmaengine PCM
  ASoC: dmaengine-pcm: Add support for platforms which can't report
  ASoC: mxs: Setup dma data in DAI probe
  ASoC: mxs: Use generic dmaengine PCM
  ASoC: imx: Setup dma data in DAI probe
  ASoC: imx: Use generic dmaengine PCM
  ASoC: omap: Setup dma data in DAI probe
  ASoC: omap: Use generic dmaengine PCM
  ASoC: ep93xx: Setup dma data in DAI probe
  ASoC: ep93xx: Use generic dmaengine PCM
  ASoC: ux500: Use generic dmaengine PCM

 include/sound/dmaengine_pcm.h         |  65 +++++++-
 include/sound/soc.h                   |   4 +
 sound/soc/Kconfig                     |   4 +
 sound/soc/Makefile                    |   4 +
 sound/soc/atmel/atmel-pcm-dma.c       |   6 +-
 sound/soc/cirrus/Kconfig              |   2 +-
 sound/soc/cirrus/ep93xx-ac97.c        |  14 +-
 sound/soc/cirrus/ep93xx-i2s.c         |  14 +-
 sound/soc/cirrus/ep93xx-pcm.c         | 137 ++--------------
 sound/soc/fsl/Kconfig                 |   2 +-
 sound/soc/fsl/fsl_ssi.c               |  19 ++-
 sound/soc/fsl/imx-pcm-dma.c           |  76 ++-------
 sound/soc/fsl/imx-pcm.c               |   6 +-
 sound/soc/fsl/imx-pcm.h               |   5 +
 sound/soc/fsl/imx-ssi.c               |  22 +--
 sound/soc/mxs/Kconfig                 |   2 +-
 sound/soc/mxs/mxs-pcm.c               | 135 ++--------------
 sound/soc/mxs/mxs-saif.c              |   3 +-
 sound/soc/omap/Kconfig                |   2 +-
 sound/soc/omap/omap-dmic.c            |   4 +-
 sound/soc/omap/omap-hdmi.c            |  12 +-
 sound/soc/omap/omap-mcbsp.c           |   6 +-
 sound/soc/omap/omap-mcpdm.c           |   7 +-
 sound/soc/omap/omap-pcm.c             | 186 ++--------------------
 sound/soc/pxa/mmp-pcm.c               |   5 +-
 sound/soc/soc-core.c                  |  85 +++++++---
 sound/soc/soc-dmaengine-pcm.c         |  82 +++++++---
 sound/soc/soc-generic-dmaengine-pcm.c | 284 ++++++++++++++++++++++++++++++++++
 sound/soc/spear/spdif_in.c            |  12 +-
 sound/soc/spear/spdif_out.c           |   7 +-
 sound/soc/spear/spear_pcm.c           | 151 ++----------------
 sound/soc/tegra/Kconfig               |   2 +-
 sound/soc/tegra/tegra_pcm.c           | 171 ++------------------
 sound/soc/ux500/Kconfig               |   2 +-
 sound/soc/ux500/ux500_pcm.c           | 159 ++-----------------
 35 files changed, 651 insertions(+), 1046 deletions(-)
 create mode 100644 sound/soc/soc-generic-dmaengine-pcm.c


More information about the Alsa-devel mailing list