1
0
Fork 0

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
Shengjiu Wang 2017-06-19 11:41:44 +08:00 committed by Jason Liu
parent cc7d78020a
commit 50e6c33117
2 changed files with 64 additions and 25 deletions

View File

@ -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.

View File

@ -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)
{