diff options
Diffstat (limited to 'sound/soc/davinci/davinci-mcasp.c')
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 103 |
1 files changed, 70 insertions, 33 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 30b94d4f9c5d..de3b155a5011 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -364,6 +364,20 @@ static irqreturn_t davinci_mcasp_rx_irq_handler(int irq, void *data) return IRQ_RETVAL(handled_mask); } +static irqreturn_t davinci_mcasp_common_irq_handler(int irq, void *data) +{ + struct davinci_mcasp *mcasp = (struct davinci_mcasp *)data; + irqreturn_t ret = IRQ_NONE; + + if (mcasp->substreams[SNDRV_PCM_STREAM_PLAYBACK]) + ret = davinci_mcasp_tx_irq_handler(irq, data); + + if (mcasp->substreams[SNDRV_PCM_STREAM_CAPTURE]) + ret |= davinci_mcasp_rx_irq_handler(irq, data); + + return ret; +} + static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { @@ -1313,16 +1327,19 @@ static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of( pdata->tx_dma_channel = dma_spec.args[0]; - ret = of_property_match_string(np, "dma-names", "rx"); - if (ret < 0) - goto nodata; + /* RX is not valid in DIT mode */ + if (pdata->op_mode != DAVINCI_MCASP_DIT_MODE) { + ret = of_property_match_string(np, "dma-names", "rx"); + if (ret < 0) + goto nodata; - ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret, - &dma_spec); - if (ret < 0) - goto nodata; + ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret, + &dma_spec); + if (ret < 0) + goto nodata; - pdata->rx_dma_channel = dma_spec.args[0]; + pdata->rx_dma_channel = dma_spec.args[0]; + } ret = of_property_read_u32(np, "tx-num-evt", &val); if (ret >= 0) @@ -1441,6 +1458,23 @@ static int davinci_mcasp_probe(struct platform_device *pdev) mcasp->dev = &pdev->dev; + irq = platform_get_irq_byname(pdev, "common"); + if (irq >= 0) { + irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_common\n", + dev_name(&pdev->dev)); + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, + davinci_mcasp_common_irq_handler, + IRQF_ONESHOT | IRQF_SHARED, + irq_name, mcasp); + if (ret) { + dev_err(&pdev->dev, "common IRQ request failed\n"); + goto err; + } + + mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK] = XUNDRN; + mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE] = ROVRN; + } + irq = platform_get_irq_byname(pdev, "rx"); if (irq >= 0) { irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_rx\n", @@ -1501,19 +1535,34 @@ static int davinci_mcasp_probe(struct platform_device *pdev) else dma_data->filter_data = &dma_params->channel; - dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE]; - dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; - dma_params->asp_chan_q = pdata->asp_chan_q; - dma_params->ram_chan_q = pdata->ram_chan_q; - dma_params->sram_pool = pdata->sram_pool; - dma_params->sram_size = pdata->sram_size_capture; - if (dat) - dma_params->dma_addr = dat->start; - else - dma_params->dma_addr = mem->start + pdata->rx_dma_offset; - - /* Unconditional dmaengine stuff */ - dma_data->addr = dma_params->dma_addr; + /* RX is not valid in DIT mode */ + if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) { + dma_params = &mcasp->dma_params[SNDRV_PCM_STREAM_CAPTURE]; + dma_data = &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; + dma_params->asp_chan_q = pdata->asp_chan_q; + dma_params->ram_chan_q = pdata->ram_chan_q; + dma_params->sram_pool = pdata->sram_pool; + dma_params->sram_size = pdata->sram_size_capture; + if (dat) + dma_params->dma_addr = dat->start; + else + dma_params->dma_addr = mem->start + pdata->rx_dma_offset; + + /* Unconditional dmaengine stuff */ + dma_data->addr = dma_params->dma_addr; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (res) + dma_params->channel = res->start; + else + dma_params->channel = pdata->rx_dma_channel; + + /* dmaengine filter data for DT and non-DT boot */ + if (pdev->dev.of_node) + dma_data->filter_data = "rx"; + else + dma_data->filter_data = &dma_params->channel; + } if (mcasp->version < MCASP_VERSION_3) { mcasp->fifo_base = DAVINCI_MCASP_V2_AFIFO_BASE; @@ -1523,18 +1572,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev) mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE; } - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (res) - dma_params->channel = res->start; - else - dma_params->channel = pdata->rx_dma_channel; - - /* dmaengine filter data for DT and non-DT boot */ - if (pdev->dev.of_node) - dma_data->filter_data = "rx"; - else - dma_data->filter_data = &dma_params->channel; - dev_set_drvdata(&pdev->dev, mcasp); mcasp_reparent_fck(pdev); |