MLK-15109-1: ASoC: fsl_esai: introduce SoC specific data
Introduce a SoC data struct which contains the differences between the different SoCs this driver supports. This makes it easy to support more differences without having to introduce a new switch/case each time. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>pull/10/head
parent
cc7d78020a
commit
50e6c33117
|
@ -8,7 +8,7 @@ other DSPs. It has up to six transmitters and four receivers.
|
|||
Required properties:
|
||||
|
||||
- compatible : Compatible list, must contain "fsl,imx6ull-esai",
|
||||
"fsl,imx8qxp-v1-esai",
|
||||
"fsl,imx8qxp-v1-esai", "fsl,imx8qm-esai"
|
||||
"fsl,imx35-esai" or "fsl,vf610-esai"
|
||||
|
||||
- reg : Offset and length of the register set for the device.
|
||||
|
|
|
@ -81,6 +81,12 @@ struct fsl_edma3_sw_tcd {
|
|||
struct fsl_edma3_hw_tcd *vtcd;
|
||||
};
|
||||
|
||||
struct fsl_esai_soc_data {
|
||||
bool imx;
|
||||
bool dma_workaround;
|
||||
bool channel_swap_workaround;
|
||||
};
|
||||
|
||||
/**
|
||||
* fsl_esai: ESAI private data
|
||||
*
|
||||
|
@ -116,6 +122,7 @@ struct fsl_esai {
|
|||
struct fsl_edma3_sw_tcd tcd_sw[4];
|
||||
struct dma_pool *tcd_pool;
|
||||
struct snd_dma_buffer buf;
|
||||
const struct fsl_esai_soc_data *soc;
|
||||
void __iomem *base_gpt0;
|
||||
void __iomem *base_gpt1;
|
||||
void __iomem *base_gpt2;
|
||||
|
@ -134,10 +141,43 @@ struct fsl_esai {
|
|||
bool sck_div[2];
|
||||
bool slave_mode;
|
||||
bool synchronous;
|
||||
bool dma_workaround;
|
||||
char name[32];
|
||||
};
|
||||
|
||||
static struct fsl_esai_soc_data fsl_esai_vf610 = {
|
||||
.imx = false,
|
||||
.dma_workaround = false,
|
||||
.channel_swap_workaround = true,
|
||||
};
|
||||
|
||||
static struct fsl_esai_soc_data fsl_esai_imx35 = {
|
||||
.imx = true,
|
||||
.dma_workaround = false,
|
||||
.channel_swap_workaround = true,
|
||||
};
|
||||
|
||||
static struct fsl_esai_soc_data fsl_esai_imx6ull = {
|
||||
.imx = true,
|
||||
.dma_workaround = false,
|
||||
.channel_swap_workaround = false,
|
||||
};
|
||||
|
||||
/* In imx8qxp rev1, the dma request signal is not revert. For esai
|
||||
* dma request is low valid, but edma assert it as high level valid.
|
||||
* so we need to use GPT to transfer the dma request signal.
|
||||
*/
|
||||
static struct fsl_esai_soc_data fsl_esai_imx8qxp_v1 = {
|
||||
.imx = true,
|
||||
.dma_workaround = true,
|
||||
.channel_swap_workaround = false,
|
||||
};
|
||||
|
||||
static struct fsl_esai_soc_data fsl_esai_imx8qm = {
|
||||
.imx = true,
|
||||
.dma_workaround = false,
|
||||
.channel_swap_workaround = false,
|
||||
};
|
||||
|
||||
static irqreturn_t esai_isr(int irq, void *devid)
|
||||
{
|
||||
struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
|
||||
|
@ -751,7 +791,7 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
|
|||
u32 bclk, mask, val;
|
||||
int ret;
|
||||
|
||||
if (esai_priv->dma_workaround)
|
||||
if (esai_priv->soc->dma_workaround)
|
||||
configure_gpt_dma(substream, dai);
|
||||
|
||||
/* Override slot_width if being specifically set */
|
||||
|
@ -878,7 +918,7 @@ static int fsl_esai_hw_free(struct snd_pcm_substream *substream,
|
|||
{
|
||||
struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
|
||||
if (esai_priv->dma_workaround)
|
||||
if (esai_priv->soc->dma_workaround)
|
||||
clear_gpt_dma(substream, cpu_dai);
|
||||
|
||||
return 0;
|
||||
|
@ -1125,9 +1165,20 @@ static void fsl_esai_reset(struct snd_pcm_substream *substream, bool stop)
|
|||
imx_start_unlock_pcm_streams(esai_priv->substream, 2, &flags);
|
||||
}
|
||||
|
||||
static const struct of_device_id fsl_esai_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx8qxp-v1-esai", .data = &fsl_esai_imx8qxp_v1 },
|
||||
{ .compatible = "fsl,imx8qm-esai", .data = &fsl_esai_imx8qm },
|
||||
{ .compatible = "fsl,imx6ull-esai", .data = &fsl_esai_imx6ull },
|
||||
{ .compatible = "fsl,imx35-esai", .data = &fsl_esai_imx35 },
|
||||
{ .compatible = "fsl,vf610-esai", .data = &fsl_esai_vf610 },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
|
||||
|
||||
static int fsl_esai_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct of_device_id *of_id;
|
||||
struct fsl_esai *esai_priv;
|
||||
struct resource *res;
|
||||
const uint32_t *iprop;
|
||||
|
@ -1145,6 +1196,12 @@ static int fsl_esai_probe(struct platform_device *pdev)
|
|||
esai_priv->pdev = pdev;
|
||||
strncpy(esai_priv->name, np->name, sizeof(esai_priv->name) - 1);
|
||||
|
||||
of_id = of_match_device(fsl_esai_dt_ids, &pdev->dev);
|
||||
if (!of_id || !of_id->data)
|
||||
return -EINVAL;
|
||||
|
||||
esai_priv->soc = of_id->data;
|
||||
|
||||
/* Get the addresses and IRQ */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
|
@ -1221,22 +1278,13 @@ static int fsl_esai_probe(struct platform_device *pdev)
|
|||
/* From imx6ull, the channel swap issue in underrun/overrun is
|
||||
* fixed in hardware. So remove the workaround.
|
||||
*/
|
||||
if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx35-esai") ||
|
||||
of_device_is_compatible(pdev->dev.of_node, "fsl,vf610-esai")) {
|
||||
if (esai_priv->soc->channel_swap_workaround) {
|
||||
esai_priv->dma_params_tx.check_xrun = fsl_esai_check_xrun;
|
||||
esai_priv->dma_params_rx.check_xrun = fsl_esai_check_xrun;
|
||||
esai_priv->dma_params_tx.device_reset = fsl_esai_reset;
|
||||
esai_priv->dma_params_rx.device_reset = fsl_esai_reset;
|
||||
}
|
||||
|
||||
/* In imx8qxp rev1, the dma request signal is not revert. For esai
|
||||
* dma request is low valid, but edma assert it as high level valid.
|
||||
* so we need to use GPT to transfer the dma request signal.
|
||||
*
|
||||
*/
|
||||
if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx8qxp-v1-esai"))
|
||||
esai_priv->dma_workaround = true;
|
||||
|
||||
esai_priv->synchronous =
|
||||
of_property_read_bool(np, "fsl,esai-synchronous");
|
||||
|
||||
|
@ -1283,7 +1331,7 @@ static int fsl_esai_probe(struct platform_device *pdev)
|
|||
buffer_size = IMX_ESAI_DMABUF_SIZE;
|
||||
|
||||
/*workaround for esai issue in imx8qxp*/
|
||||
if (esai_priv->dma_workaround) {
|
||||
if (esai_priv->soc->dma_workaround) {
|
||||
esai_priv->tcd_pool = dma_pool_create("tcd_pool_esai",
|
||||
&esai_priv->pdev->dev,
|
||||
sizeof(struct fsl_edma3_hw_tcd), 32, 0);
|
||||
|
@ -1354,7 +1402,7 @@ static int fsl_esai_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct fsl_esai *esai_priv = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
if (esai_priv->dma_workaround) {
|
||||
if (esai_priv->soc->dma_workaround) {
|
||||
dma_free_writecombine(&esai_priv->pdev->dev,
|
||||
0x1000,
|
||||
esai_priv->buf.area,
|
||||
|
@ -1379,15 +1427,6 @@ static int fsl_esai_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id fsl_esai_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx8qxp-v1-esai", },
|
||||
{ .compatible = "fsl,imx6ull-esai", },
|
||||
{ .compatible = "fsl,imx35-esai", },
|
||||
{ .compatible = "fsl,vf610-esai", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int fsl_esai_suspend(struct device *dev)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue