Commit 787a46c0 authored by Mark Brown's avatar Mark Brown

Merge series "ASoC: Add new module driver for new ASRC" from Shengjiu Wang <shengjiu.wang@nxp.com>:

Add new module driver for new ASRC in i.MX8MN, several commits
are added for new property fsl,asrc-format

Shengjiu Wang (7):
  ASoC: fsl_asrc: rename asrc_priv to asrc
  ASoC: dt-bindings: fsl_asrc: Add new property fsl,asrc-format
  ASoC: fsl-asoc-card: Support new property fsl,asrc-format
  ASoC: fsl_asrc: Support new property fsl,asrc-format
  ASoC: fsl_asrc: Move common definition to fsl_asrc_common
  ASoC: dt-bindings: fsl_easrc: Add document for EASRC
  ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers

changes in v9
- use lowercase for dt example.

changes in v8
- change get_pair_priv_size to pair_priv_size variable

changes in v7
- updated according to Nicoin's comments.
- add get_pair_priv_size to replace PAIR_PRIVATE_SIZE

changes in v6
- updated according to Nicoin's and Rob's comments.

changes in v5
- Add new property fsl,asrc-format, rather than change fsl,asrc-width
  to fsl,asrc-formt.
- code change for above change.

changes in v4
- Add several commit for changing DT binding asrc-width to asrc-format
- rename asrc_priv to asrc

changes in v3
- add new commit "ASoC: fsl_asrc: Change asrc_width to asrc_format"
- modify binding doc to yaml format
- remove fsl_easrc_dma.c, make fsl_asrc_dma.c useable for easrc.

changes in v2
- change i.MX815 to i.MX8MN
- Add changes in Kconfig and Makefile

 .../devicetree/bindings/sound/fsl,asrc.txt    |    4 +
 .../devicetree/bindings/sound/fsl,easrc.yaml  |  101 +
 sound/soc/fsl/Kconfig                         |   11 +
 sound/soc/fsl/Makefile                        |    2 +
 sound/soc/fsl/fsl-asoc-card.c                 |   24 +-
 sound/soc/fsl/fsl_asrc.c                      |  305 +--
 sound/soc/fsl/fsl_asrc.h                      |   74 +-
 sound/soc/fsl/fsl_asrc_common.h               |  106 +
 sound/soc/fsl/fsl_asrc_dma.c                  |   54 +-
 sound/soc/fsl/fsl_easrc.c                     | 2114 +++++++++++++++++
 sound/soc/fsl/fsl_easrc.h                     |  651 +++++
 11 files changed, 3212 insertions(+), 234 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,easrc.yaml
 create mode 100644 sound/soc/fsl/fsl_asrc_common.h
 create mode 100644 sound/soc/fsl/fsl_easrc.c
 create mode 100644 sound/soc/fsl/fsl_easrc.h

--
2.21.0
parents 8baa3b5a 955ac624
...@@ -51,6 +51,10 @@ Optional properties: ...@@ -51,6 +51,10 @@ Optional properties:
will be in use as default. Otherwise, the big endian will be in use as default. Otherwise, the big endian
mode will be in use for all the device registers. mode will be in use for all the device registers.
- fsl,asrc-format : Defines a mutual sample format used by DPCM Back
Ends, which can replace the fsl,asrc-width.
The value is 2 (S16_LE), or 6 (S24_LE).
Example: Example:
asrc: asrc@2034000 { asrc: asrc@2034000 {
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/fsl,easrc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP Asynchronous Sample Rate Converter (ASRC) Controller
maintainers:
- Shengjiu Wang <shengjiu.wang@nxp.com>
properties:
$nodename:
pattern: "^easrc@.*"
compatible:
const: fsl,imx8mn-easrc
reg:
maxItems: 1
interrupts:
maxItems: 1
clocks:
items:
- description: Peripheral clock
clock-names:
items:
- const: mem
dmas:
maxItems: 8
dma-names:
items:
- const: ctx0_rx
- const: ctx0_tx
- const: ctx1_rx
- const: ctx1_tx
- const: ctx2_rx
- const: ctx2_tx
- const: ctx3_rx
- const: ctx3_tx
firmware-name:
allOf:
- $ref: /schemas/types.yaml#/definitions/string
- const: imx/easrc/easrc-imx8mn.bin
description: The coefficient table for the filters
fsl,asrc-rate:
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32
- minimum: 8000
- maximum: 192000
description: Defines a mutual sample rate used by DPCM Back Ends
fsl,asrc-format:
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32
- enum: [2, 6, 10, 32, 36]
default: 2
description:
Defines a mutual sample format used by DPCM Back Ends
required:
- compatible
- reg
- interrupts
- clocks
- clock-names
- dmas
- dma-names
- firmware-name
- fsl,asrc-rate
- fsl,asrc-format
examples:
- |
#include <dt-bindings/clock/imx8mn-clock.h>
easrc: easrc@300c0000 {
compatible = "fsl,imx8mn-easrc";
reg = <0x0 0x300c0000 0x0 0x10000>;
interrupts = <0x0 122 0x4>;
clocks = <&clk IMX8MN_CLK_ASRC_ROOT>;
clock-names = "mem";
dmas = <&sdma2 16 23 0> , <&sdma2 17 23 0>,
<&sdma2 18 23 0> , <&sdma2 19 23 0>,
<&sdma2 20 23 0> , <&sdma2 21 23 0>,
<&sdma2 22 23 0> , <&sdma2 23 23 0>;
dma-names = "ctx0_rx", "ctx0_tx",
"ctx1_rx", "ctx1_tx",
"ctx2_rx", "ctx2_tx",
"ctx3_rx", "ctx3_tx";
firmware-name = "imx/easrc/easrc-imx8mn.bin";
fsl,asrc-rate = <8000>;
fsl,asrc-format = <2>;
};
...@@ -84,6 +84,17 @@ config SND_SOC_FSL_MICFIL ...@@ -84,6 +84,17 @@ config SND_SOC_FSL_MICFIL
Say Y if you want to add Pulse Density Modulation microphone Say Y if you want to add Pulse Density Modulation microphone
interface (MICFIL) support for NXP. interface (MICFIL) support for NXP.
config SND_SOC_FSL_EASRC
tristate "Enhanced Asynchronous Sample Rate Converter (EASRC) module support"
depends on SND_SOC_FSL_ASRC
select REGMAP_MMIO
select SND_SOC_GENERIC_DMAENGINE_PCM
help
Say Y if you want to add Enhanced ASRC support for NXP. The ASRC is
a digital module that converts audio from a source sample rate to a
destination sample rate. It is a new design module compare with the
old ASRC.
config SND_SOC_FSL_UTILS config SND_SOC_FSL_UTILS
tristate tristate
......
...@@ -24,6 +24,7 @@ snd-soc-fsl-micfil-objs := fsl_micfil.o ...@@ -24,6 +24,7 @@ snd-soc-fsl-micfil-objs := fsl_micfil.o
snd-soc-fsl-utils-objs := fsl_utils.o snd-soc-fsl-utils-objs := fsl_utils.o
snd-soc-fsl-dma-objs := fsl_dma.o snd-soc-fsl-dma-objs := fsl_dma.o
snd-soc-fsl-mqs-objs := fsl_mqs.o snd-soc-fsl-mqs-objs := fsl_mqs.o
snd-soc-fsl-easrc-objs := fsl_easrc.o
obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o
obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
...@@ -35,6 +36,7 @@ obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o ...@@ -35,6 +36,7 @@ obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
obj-$(CONFIG_SND_SOC_FSL_MICFIL) += snd-soc-fsl-micfil.o obj-$(CONFIG_SND_SOC_FSL_MICFIL) += snd-soc-fsl-micfil.o
obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
obj-$(CONFIG_SND_SOC_FSL_MQS) += snd-soc-fsl-mqs.o obj-$(CONFIG_SND_SOC_FSL_MQS) += snd-soc-fsl-mqs.o
obj-$(CONFIG_SND_SOC_FSL_EASRC) += snd-soc-fsl-easrc.o
obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
# MPC5200 Platform Support # MPC5200 Platform Support
......
...@@ -680,10 +680,15 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) ...@@ -680,10 +680,15 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
goto asrc_fail; goto asrc_fail;
} }
ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width); ret = of_property_read_u32(asrc_np, "fsl,asrc-format",
&priv->asrc_format);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to get output rate\n"); /* Fallback to old binding; translate to asrc_format */
ret = -EINVAL; ret = of_property_read_u32(asrc_np, "fsl,asrc-width",
&width);
if (ret) {
dev_err(&pdev->dev,
"failed to decide output format\n");
goto asrc_fail; goto asrc_fail;
} }
...@@ -692,6 +697,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) ...@@ -692,6 +697,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
else else
priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE; priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE;
} }
}
/* Finish card registering */ /* Finish card registering */
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
......
This diff is collapsed.
...@@ -10,8 +10,7 @@ ...@@ -10,8 +10,7 @@
#ifndef _FSL_ASRC_H #ifndef _FSL_ASRC_H
#define _FSL_ASRC_H #define _FSL_ASRC_H
#define IN 0 #include "fsl_asrc_common.h"
#define OUT 1
#define ASRC_DMA_BUFFER_NUM 2 #define ASRC_DMA_BUFFER_NUM 2
#define ASRC_INPUTFIFO_THRESHOLD 32 #define ASRC_INPUTFIFO_THRESHOLD 32
...@@ -283,14 +282,6 @@ ...@@ -283,14 +282,6 @@
#define ASRMCR1i_OW16_MASK (1 << ASRMCR1i_OW16_SHIFT) #define ASRMCR1i_OW16_MASK (1 << ASRMCR1i_OW16_SHIFT)
#define ASRMCR1i_OW16(v) ((v) << ASRMCR1i_OW16_SHIFT) #define ASRMCR1i_OW16(v) ((v) << ASRMCR1i_OW16_SHIFT)
enum asrc_pair_index {
ASRC_INVALID_PAIR = -1,
ASRC_PAIR_A = 0,
ASRC_PAIR_B = 1,
ASRC_PAIR_C = 2,
};
#define ASRC_PAIR_MAX_NUM (ASRC_PAIR_C + 1) #define ASRC_PAIR_MAX_NUM (ASRC_PAIR_C + 1)
enum asrc_inclk { enum asrc_inclk {
...@@ -446,83 +437,28 @@ struct fsl_asrc_soc_data { ...@@ -446,83 +437,28 @@ struct fsl_asrc_soc_data {
}; };
/** /**
* fsl_asrc_pair: ASRC Pair private data * fsl_asrc_pair_priv: ASRC Pair private data
* *
* @asrc_priv: pointer to its parent module
* @config: configuration profile * @config: configuration profile
* @error: error record
* @index: pair index (ASRC_PAIR_A, ASRC_PAIR_B, ASRC_PAIR_C)
* @channels: occupied channel number
* @desc: input and output dma descriptors
* @dma_chan: inputer and output DMA channels
* @dma_data: private dma data
* @pos: hardware pointer position
* @private: pair private area
*/ */
struct fsl_asrc_pair { struct fsl_asrc_pair_priv {
struct fsl_asrc *asrc_priv;
struct asrc_config *config; struct asrc_config *config;
unsigned int error;
enum asrc_pair_index index;
unsigned int channels;
struct dma_async_tx_descriptor *desc[2];
struct dma_chan *dma_chan[2];
struct imx_dma_data dma_data;
unsigned int pos;
void *private;
}; };
/** /**
* fsl_asrc_pair: ASRC private data * fsl_asrc_priv: ASRC private data
* *
* @dma_params_rx: DMA parameters for receive channel
* @dma_params_tx: DMA parameters for transmit channel
* @pdev: platform device pointer
* @regmap: regmap handler
* @paddr: physical address to the base address of registers
* @mem_clk: clock source to access register
* @ipg_clk: clock source to drive peripheral
* @spba_clk: SPBA clock (optional, depending on SoC design)
* @asrck_clk: clock sources to driver ASRC internal logic * @asrck_clk: clock sources to driver ASRC internal logic
* @lock: spin lock for resource protection
* @pair: pair pointers
* @soc: soc specific data * @soc: soc specific data
* @channel_avail: non-occupied channel numbers
* @clk_map: clock map for input/output clock * @clk_map: clock map for input/output clock
* @asrc_rate: default sample rate for ASoC Back-Ends
* @asrc_width: default sample width for ASoC Back-Ends
* @regcache_cfg: store register value of REG_ASRCFG * @regcache_cfg: store register value of REG_ASRCFG
*/ */
struct fsl_asrc { struct fsl_asrc_priv {
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct platform_device *pdev;
struct regmap *regmap;
unsigned long paddr;
struct clk *mem_clk;
struct clk *ipg_clk;
struct clk *spba_clk;
struct clk *asrck_clk[ASRC_CLK_MAX_NUM]; struct clk *asrck_clk[ASRC_CLK_MAX_NUM];
spinlock_t lock;
struct fsl_asrc_pair *pair[ASRC_PAIR_MAX_NUM];
const struct fsl_asrc_soc_data *soc; const struct fsl_asrc_soc_data *soc;
unsigned int channel_avail;
unsigned char *clk_map[2]; unsigned char *clk_map[2];
int asrc_rate;
int asrc_width;
u32 regcache_cfg; u32 regcache_cfg;
}; };
#define DRV_NAME "fsl-asrc-dai"
extern struct snd_soc_component_driver fsl_asrc_component;
struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir);
int fsl_asrc_request_pair(int channels, struct fsl_asrc_pair *pair);
void fsl_asrc_release_pair(struct fsl_asrc_pair *pair);
#endif /* _FSL_ASRC_H */ #endif /* _FSL_ASRC_H */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2019 NXP
*
*/
#ifndef _FSL_ASRC_COMMON_H
#define _FSL_ASRC_COMMON_H
/* directions */
#define IN 0
#define OUT 1
enum asrc_pair_index {
ASRC_INVALID_PAIR = -1,
ASRC_PAIR_A = 0,
ASRC_PAIR_B = 1,
ASRC_PAIR_C = 2,
ASRC_PAIR_D = 3,
};
#define PAIR_CTX_NUM 0x4
/**
* fsl_asrc_pair: ASRC Pair common data
*
* @asrc: pointer to its parent module
* @error: error record
* @index: pair index (ASRC_PAIR_A, ASRC_PAIR_B, ASRC_PAIR_C)
* @channels: occupied channel number
* @desc: input and output dma descriptors
* @dma_chan: inputer and output DMA channels
* @dma_data: private dma data
* @pos: hardware pointer position
* @private: pair private area
*/
struct fsl_asrc_pair {
struct fsl_asrc *asrc;
unsigned int error;
enum asrc_pair_index index;
unsigned int channels;
struct dma_async_tx_descriptor *desc[2];
struct dma_chan *dma_chan[2];
struct imx_dma_data dma_data;
unsigned int pos;
void *private;
};
/**
* fsl_asrc: ASRC common data
*
* @dma_params_rx: DMA parameters for receive channel
* @dma_params_tx: DMA parameters for transmit channel
* @pdev: platform device pointer
* @regmap: regmap handler
* @paddr: physical address to the base address of registers
* @mem_clk: clock source to access register
* @ipg_clk: clock source to drive peripheral
* @spba_clk: SPBA clock (optional, depending on SoC design)
* @lock: spin lock for resource protection
* @pair: pair pointers
* @channel_avail: non-occupied channel numbers
* @asrc_rate: default sample rate for ASoC Back-Ends
* @asrc_format: default sample format for ASoC Back-Ends
* @use_edma: edma is used
* @get_dma_channel: function pointer
* @request_pair: function pointer
* @release_pair: function pointer
* @get_fifo_addr: function pointer
* @pair_priv_size: size of pair private struct.
* @private: private data structure
*/
struct fsl_asrc {
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct platform_device *pdev;
struct regmap *regmap;
unsigned long paddr;
struct clk *mem_clk;
struct clk *ipg_clk;
struct clk *spba_clk;
spinlock_t lock; /* spin lock for resource protection */
struct fsl_asrc_pair *pair[PAIR_CTX_NUM];
unsigned int channel_avail;
int asrc_rate;
snd_pcm_format_t asrc_format;
bool use_edma;
struct dma_chan *(*get_dma_channel)(struct fsl_asrc_pair *pair, bool dir);
int (*request_pair)(int channels, struct fsl_asrc_pair *pair);
void (*release_pair)(struct fsl_asrc_pair *pair);
int (*get_fifo_addr)(u8 dir, enum asrc_pair_index index);
size_t pair_priv_size;
void *private;
};
#define DRV_NAME "fsl-asrc-dai"
extern struct snd_soc_component_driver fsl_asrc_component;
#endif /* _FSL_ASRC_COMMON_H */
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <sound/dmaengine_pcm.h> #include <sound/dmaengine_pcm.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include "fsl_asrc.h" #include "fsl_asrc_common.h"
#define FSL_ASRC_DMABUF_SIZE (256 * 1024) #define FSL_ASRC_DMABUF_SIZE (256 * 1024)
...@@ -135,7 +135,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, ...@@ -135,7 +135,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
struct snd_dmaengine_dai_dma_data *dma_params_be = NULL; struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data; struct fsl_asrc_pair *pair = runtime->private_data;
struct fsl_asrc *asrc_priv = pair->asrc_priv; struct fsl_asrc *asrc = pair->asrc;
struct dma_slave_config config_fe, config_be; struct dma_slave_config config_fe, config_be;
enum asrc_pair_index index = pair->index; enum asrc_pair_index index = pair->index;
struct device *dev = component->dev; struct device *dev = component->dev;
...@@ -146,7 +146,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, ...@@ -146,7 +146,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
struct device *dev_be; struct device *dev_be;
u8 dir = tx ? OUT : IN; u8 dir = tx ? OUT : IN;
dma_cap_mask_t mask; dma_cap_mask_t mask;
int ret; int ret, width;
/* Fetch the Back-End dma_data from DPCM */ /* Fetch the Back-End dma_data from DPCM */
for_each_dpcm_be(rtd, stream, dpcm) { for_each_dpcm_be(rtd, stream, dpcm) {
...@@ -170,10 +170,10 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, ...@@ -170,10 +170,10 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
/* Override dma_data of the Front-End and config its dmaengine */ /* Override dma_data of the Front-End and config its dmaengine */
dma_params_fe = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); dma_params_fe = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream);
dma_params_fe->addr = asrc_priv->paddr + REG_ASRDx(!dir, index); dma_params_fe->addr = asrc->paddr + asrc->get_fifo_addr(!dir, index);
dma_params_fe->maxburst = dma_params_be->maxburst; dma_params_fe->maxburst = dma_params_be->maxburst;
pair->dma_chan[!dir] = fsl_asrc_get_dma_channel(pair, !dir); pair->dma_chan[!dir] = asrc->get_dma_channel(pair, !dir);
if (!pair->dma_chan[!dir]) { if (!pair->dma_chan[!dir]) {
dev_err(dev, "failed to request DMA channel\n"); dev_err(dev, "failed to request DMA channel\n");
return -EINVAL; return -EINVAL;
...@@ -203,7 +203,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, ...@@ -203,7 +203,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
* need to configure dma_request and dma_request2, but get dma_chan via * need to configure dma_request and dma_request2, but get dma_chan via
* dma_request_slave_channel directly with dma name of Front-End device * dma_request_slave_channel directly with dma name of Front-End device
*/ */
if (!asrc_priv->soc->use_edma) { if (!asrc->use_edma) {
/* Get DMA request of Back-End */ /* Get DMA request of Back-End */
tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx"); tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
tmp_data = tmp_chan->private; tmp_data = tmp_chan->private;
...@@ -211,7 +211,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, ...@@ -211,7 +211,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
dma_release_channel(tmp_chan); dma_release_channel(tmp_chan);
/* Get DMA request of Front-End */ /* Get DMA request of Front-End */
tmp_chan = fsl_asrc_get_dma_channel(pair, dir); tmp_chan = asrc->get_dma_channel(pair, dir);
tmp_data = tmp_chan->private; tmp_data = tmp_chan->private;
pair->dma_data.dma_request2 = tmp_data->dma_request; pair->dma_data.dma_request2 = tmp_data->dma_request;
pair->dma_data.peripheral_type = tmp_data->peripheral_type; pair->dma_data.peripheral_type = tmp_data->peripheral_type;
...@@ -222,7 +222,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, ...@@ -222,7 +222,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
dma_request_channel(mask, filter, &pair->dma_data); dma_request_channel(mask, filter, &pair->dma_data);
} else { } else {
pair->dma_chan[dir] = pair->dma_chan[dir] =
fsl_asrc_get_dma_channel(pair, dir); asrc->get_dma_channel(pair, dir);
} }
if (!pair->dma_chan[dir]) { if (!pair->dma_chan[dir]) {
...@@ -230,10 +230,19 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, ...@@ -230,10 +230,19 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
return -EINVAL; return -EINVAL;
} }
if (asrc_priv->asrc_width == 16) width = snd_pcm_format_physical_width(asrc->asrc_format);
if (width < 8 || width > 64)
return -EINVAL;
else if (width == 8)
buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
else if (width == 16)
buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
else else if (width == 24)
buswidth = DMA_SLAVE_BUSWIDTH_3_BYTES;
else if (width <= 32)
buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
else
buswidth = DMA_SLAVE_BUSWIDTH_8_BYTES;
config_be.direction = DMA_DEV_TO_DEV; config_be.direction = DMA_DEV_TO_DEV;
config_be.src_addr_width = buswidth; config_be.src_addr_width = buswidth;
...@@ -242,10 +251,10 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, ...@@ -242,10 +251,10 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component,
config_be.dst_maxburst = dma_params_be->maxburst; config_be.dst_maxburst = dma_params_be->maxburst;
if (tx) { if (tx) {
config_be.src_addr = asrc_priv->paddr + REG_ASRDO(index); config_be.src_addr = asrc->paddr + asrc->get_fifo_addr(OUT, index);
config_be.dst_addr = dma_params_be->addr; config_be.dst_addr = dma_params_be->addr;
} else { } else {
config_be.dst_addr = asrc_priv->paddr + REG_ASRDI(index); config_be.dst_addr = asrc->paddr + asrc->get_fifo_addr(IN, index);
config_be.src_addr = dma_params_be->addr; config_be.src_addr = dma_params_be->addr;
} }
...@@ -288,7 +297,7 @@ static int fsl_asrc_dma_startup(struct snd_soc_component *component, ...@@ -288,7 +297,7 @@ static int fsl_asrc_dma_startup(struct snd_soc_component *component,
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dmaengine_dai_dma_data *dma_data; struct snd_dmaengine_dai_dma_data *dma_data;
struct device *dev = component->dev; struct device *dev = component->dev;
struct fsl_asrc *asrc_priv = dev_get_drvdata(dev); struct fsl_asrc *asrc = dev_get_drvdata(dev);
struct fsl_asrc_pair *pair; struct fsl_asrc_pair *pair;
struct dma_chan *tmp_chan = NULL; struct dma_chan *tmp_chan = NULL;
u8 dir = tx ? OUT : IN; u8 dir = tx ? OUT : IN;
...@@ -302,11 +311,12 @@ static int fsl_asrc_dma_startup(struct snd_soc_component *component, ...@@ -302,11 +311,12 @@ static int fsl_asrc_dma_startup(struct snd_soc_component *component,
return ret; return ret;
} }
pair = kzalloc(sizeof(struct fsl_asrc_pair), GFP_KERNEL); pair = kzalloc(sizeof(*pair) + asrc->pair_priv_size, GFP_KERNEL);
if (!pair) if (!pair)
return -ENOMEM; return -ENOMEM;
pair->asrc_priv = asrc_priv; pair->asrc = asrc;
pair->private = (void *)pair + sizeof(struct fsl_asrc_pair);
runtime->private_data = pair; runtime->private_data = pair;
...@@ -314,14 +324,14 @@ static int fsl_asrc_dma_startup(struct snd_soc_component *component, ...@@ -314,14 +324,14 @@ static int fsl_asrc_dma_startup(struct snd_soc_component *component,
* Request pair function needs channel num as input, for this * Request pair function needs channel num as input, for this
* dummy pair, we just request "1" channel temporarily. * dummy pair, we just request "1" channel temporarily.
*/ */
ret = fsl_asrc_request_pair(1, pair); ret = asrc->request_pair(1, pair);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "failed to request asrc pair\n"); dev_err(dev, "failed to request asrc pair\n");
goto req_pair_err; goto req_pair_err;
} }
/* Request a dummy dma channel, which will be released later. */ /* Request a dummy dma channel, which will be released later. */
tmp_chan = fsl_asrc_get_dma_channel(pair, dir); tmp_chan = asrc->get_dma_channel(pair, dir);
if (!tmp_chan) { if (!tmp_chan) {
dev_err(dev, "failed to get dma channel\n"); dev_err(dev, "failed to get dma channel\n");
ret = -EINVAL; ret = -EINVAL;
...@@ -347,7 +357,7 @@ static int fsl_asrc_dma_startup(struct snd_soc_component *component, ...@@ -347,7 +357,7 @@ static int fsl_asrc_dma_startup(struct snd_soc_component *component,
dma_release_channel(tmp_chan); dma_release_channel(tmp_chan);
dma_chan_err: dma_chan_err:
fsl_asrc_release_pair(pair); asrc->release_pair(pair);
req_pair_err: req_pair_err:
if (release_pair) if (release_pair)
...@@ -361,15 +371,15 @@ static int fsl_asrc_dma_shutdown(struct snd_soc_component *component, ...@@ -361,15 +371,15 @@ static int fsl_asrc_dma_shutdown(struct snd_soc_component *component,
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data; struct fsl_asrc_pair *pair = runtime->private_data;
struct fsl_asrc *asrc_priv; struct fsl_asrc *asrc;
if (!pair) if (!pair)
return 0; return 0;
asrc_priv = pair->asrc_priv; asrc = pair->asrc;
if (asrc_priv->pair[pair->index] == pair) if (asrc->pair[pair->index] == pair)
asrc_priv->pair[pair->index] = NULL; asrc->pair[pair->index] = NULL;
kfree(pair); kfree(pair);
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment