summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjenny.zhang <jenny.zhang@starfivetech.com>2022-01-28 09:30:49 +0300
committerjenny.zhang <jenny.zhang@starfivetech.com>2022-01-28 09:30:49 +0300
commitf51ce469059cd1aec79a6981ec3ebd4b957a41b4 (patch)
tree1db30b72f6d9cfd476123cd195a201f294812065
parent7d3709aaf0e97c008e52595bb723cb8e4a11d0e6 (diff)
downloadlinux-visionfive-5.13.y-devel.tar.xz
1.[alsa]Resolve the failure of pwmdac to play mono 8K audiovisionfive-5.13.y-devel
2.[dma] Modify the DMA error interrupt handling process Signed-off-by: jenny.zhang <jenny.zhang@starfivetech.com>
-rwxr-xr-x[-rw-r--r--]drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c204
-rwxr-xr-x[-rw-r--r--]drivers/dma/dw-axi-dmac/dw-axi-dmac.h1
-rwxr-xr-xsound/core/pcm_native.c6
-rwxr-xr-x[-rw-r--r--]sound/soc/starfive/starfive_pwmdac.c77
4 files changed, 92 insertions, 196 deletions
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 60f56e670919..ddc235df4c3b 100644..100755
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -309,13 +309,12 @@ dma_chan_tx_status(struct dma_chan *dchan, dma_cookie_t cookie,
len = vd_to_axi_desc(vdesc)->hw_desc[0].len;
completed_length = completed_blocks * len;
bytes = length - completed_length;
+ spin_unlock_irqrestore(&chan->vc.lock, flags);
+ dma_set_residue(txstate, bytes);
} else {
- bytes = vd_to_axi_desc(vdesc)->length;
+ spin_unlock_irqrestore(&chan->vc.lock, flags);
}
- spin_unlock_irqrestore(&chan->vc.lock, flags);
- dma_set_residue(txstate, bytes);
-
return status;
}
@@ -329,64 +328,29 @@ static void write_chan_llp(struct axi_dma_chan *chan, dma_addr_t adr)
axi_chan_iowrite64(chan, CH_LLP, adr);
}
-static void dw_axi_dma_set_byte_halfword(struct axi_dma_chan *chan, bool set)
-{
- u32 offset = DMAC_APB_BYTE_WR_CH_EN;
- u32 reg_width, val;
-
- if (!chan->chip->apb_regs) {
- dev_dbg(chan->chip->dev, "apb_regs not initialized\n");
- return;
- }
-
- reg_width = __ffs(chan->config.dst_addr_width);
- if (reg_width == DWAXIDMAC_TRANS_WIDTH_16)
- offset = DMAC_APB_HALFWORD_WR_CH_EN;
-
- val = ioread32(chan->chip->apb_regs + offset);
-
- if (set)
- val |= BIT(chan->id);
- else
- val &= ~BIT(chan->id);
-
- iowrite32(val, chan->chip->apb_regs + offset);
-}
/* Called in chan locked context */
static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
struct axi_dma_desc *first)
{
+ struct axi_dma_hw_desc *hw_desc = NULL;
u32 priority = chan->chip->dw->hdata->priority[chan->id];
u32 reg, irq_mask;
+ s32 descs_flush, descs_count;
u8 lms = 0; /* Select AXI0 master for LLI fetching */
-#ifdef CONFIG_DW_AXI_DMAC_STARFIVE
- s32 descs_flush, descs_count;
- struct axi_dma_hw_desc *hw_desc = NULL;
- chan->is_err = false;
if (unlikely(axi_chan_is_hw_enable(chan))) {
dev_err(chan2dev(chan), "%s is non-idle!\n",
axi_chan_name(chan));
axi_chan_disable(chan);
- chan->is_err = true;
//return;
}
-#else
- if (unlikely(axi_chan_is_hw_enable(chan))) {
- dev_err(chan2dev(chan), "%s is non-idle!\n",
- axi_chan_name(chan));
-
- return;
- }
-#endif
axi_dma_enable(chan->chip);
reg = (DWAXIDMAC_MBLK_TYPE_LL << CH_CFG_L_DST_MULTBLK_TYPE_POS |
DWAXIDMAC_MBLK_TYPE_LL << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
-#ifdef CONFIG_DW_AXI_DMAC_STARFIVE
if (chan->hw_handshake_num) {
switch (chan->direction) {
case DMA_MEM_TO_DEV:
@@ -399,7 +363,6 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
break;
}
}
-#endif
axi_chan_iowrite32(chan, CH_CFG_L, reg);
@@ -409,7 +372,6 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
DWAXIDMAC_HS_SEL_HW << CH_CFG_H_HS_SEL_SRC_POS);
switch (chan->direction) {
case DMA_MEM_TO_DEV:
- dw_axi_dma_set_byte_halfword(chan, true);
reg |= (chan->config.device_fc ?
DWAXIDMAC_TT_FC_MEM_TO_PER_DST :
DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC)
@@ -435,23 +397,13 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan,
irq_mask |= DWAXIDMAC_IRQ_SUSPENDED;
axi_chan_irq_set(chan, irq_mask);
- /* flush all the desc */
-#ifdef CONFIG_DW_AXI_DMAC_STARFIVE
+ /*flush all the desc */
+#ifdef CONFIG_SOC_STARFIVE_VIC7100
if(chan->chip->flag->need_flush) {
- int count = atomic_read(&chan->descs_allocated);
- int i;
-
- for (i = 0; i < count; i++) {
- starfive_flush_dcache(first->hw_desc[i].llp,
- sizeof(*first->hw_desc[i].lli));
-
- dev_dbg(chan->chip->dev,
- "sar:%#llx dar:%#llx llp:%#llx ctl:0x%x:%08x\n",
- first->hw_desc[i].lli->sar,
- first->hw_desc[i].lli->dar,
- first->hw_desc[i].lli->llp,
- first->hw_desc[i].lli->ctl_hi,
- first->hw_desc[i].lli->ctl_lo);
+ descs_count = atomic_read(&chan->descs_allocated);
+ for (descs_flush = 0; descs_flush < descs_count; descs_flush++) {
+ hw_desc = &first->hw_desc[descs_flush];
+ starfive_flush_dcache(hw_desc->llp, sizeof(*hw_desc->lli));
}
}
#endif
@@ -542,48 +494,6 @@ static void dma_chan_free_chan_resources(struct dma_chan *dchan)
pm_runtime_put(chan->chip->dev);
}
-static void dw_axi_dma_set_hw_channel(struct axi_dma_chip *chip,
- u32 handshake_num, bool set)
-{
- unsigned long start = 0;
- unsigned long reg_value;
- unsigned long reg_mask;
- unsigned long reg_set;
- unsigned long mask;
- unsigned long val;
-
- if (!chip->apb_regs) {
- dev_dbg(chip->dev, "apb_regs not initialized\n");
- return;
- }
-
- /*
- * An unused DMA channel has a default value of 0x3F.
- * Lock the DMA channel by assign a handshake number to the channel.
- * Unlock the DMA channel by assign 0x3F to the channel.
- */
- if (set) {
- reg_set = UNUSED_CHANNEL;
- val = handshake_num;
- } else {
- reg_set = handshake_num;
- val = UNUSED_CHANNEL;
- }
-
- reg_value = lo_hi_readq(chip->apb_regs + DMAC_APB_HW_HS_SEL_0);
-
- for_each_set_clump8(start, reg_mask, &reg_value, 64) {
- if (reg_mask == reg_set) {
- mask = GENMASK_ULL(start + 7, start);
- reg_value &= ~mask;
- reg_value |= rol64(val, start);
- lo_hi_writeq(reg_value,
- chip->apb_regs + DMAC_APB_HW_HS_SEL_0);
- break;
- }
- }
-}
-
/*
* If DW_axi_dmac sees CHx_CTL.ShadowReg_Or_LLI_Last bit of the fetched LLI
* as 1, it understands that the current block is the final block in the
@@ -709,7 +619,7 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
-#ifdef CONFIG_DW_AXI_DMAC_STARFIVE
+ #ifdef CONFIG_SOC_STARFIVE_VIC7100
ctllo |= DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_DST_MSIZE_POS |
DWAXIDMAC_BURST_TRANS_LEN_16 << CH_CTL_L_SRC_MSIZE_POS;
#else
@@ -819,8 +729,6 @@ dw_axi_dma_chan_prep_cyclic(struct dma_chan *dchan, dma_addr_t dma_addr,
llp = hw_desc->llp;
} while (total_segments);
- dw_axi_dma_set_hw_channel(chan->chip, chan->hw_handshake_num, true);
-
return vchan_tx_prep(&chan->vc, &desc->vd, flags);
err_desc_get:
@@ -899,8 +807,6 @@ dw_axi_dma_chan_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
llp = hw_desc->llp;
} while (num_sgs);
- dw_axi_dma_set_hw_channel(chan->chip, chan->hw_handshake_num, true);
-
return vchan_tx_prep(&chan->vc, &desc->vd, flags);
err_desc_get:
@@ -996,6 +902,10 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
num++;
}
+ /* Total len of src/dest sg == 0, so no descriptor were allocated */
+ if (unlikely(!desc))
+ return NULL;
+
/* Set end-of-link to the last link descriptor of list */
set_desc_last(&desc->hw_desc[num - 1]);
/* Managed transfer list */
@@ -1046,16 +956,23 @@ static void axi_chan_list_dump_lli(struct axi_dma_chan *chan,
axi_chan_dump_lli(chan, &desc_head->hw_desc[i]);
}
-static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
+
+static void axi_chan_tasklet(struct tasklet_struct *t)
{
+ struct axi_dma_chan *chan = from_tasklet(chan, t, dma_tasklet);
struct virt_dma_desc *vd;
+ u32 chan_active = BIT(chan->id) << DMAC_CHAN_EN_SHIFT;
unsigned long flags;
-#ifdef CONFIG_DW_AXI_DMAC_STARFIVE
- struct axi_dma_desc *desc;
-#endif
- spin_lock_irqsave(&chan->vc.lock, flags);
+ u32 val;
+ int ret;
- axi_chan_disable(chan);
+ ret = readl_poll_timeout_atomic(chan->chip->regs + DMAC_CHEN, val,
+ !(val & chan_active), 10, 2000);
+ if (ret == -ETIMEDOUT)
+ dev_warn(chan2dev(chan),
+ "irq %s failed to stop\n", axi_chan_name(chan));
+
+ spin_lock_irqsave(&chan->vc.lock, flags);
/* The bad descriptor currently is in the head of vc list */
vd = vchan_next_desc(&chan->vc);
@@ -1065,33 +982,43 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
spin_unlock_irqrestore(&chan->vc.lock, flags);
return;
}
-#ifdef CONFIG_DW_AXI_DMAC_STARFIVE
- if (chan->is_err) {
- desc = vd_to_axi_desc(vd);
- axi_chan_block_xfer_start(chan, desc);
- chan->is_err = false;
+
+ if (chan->cyclic) {
+ vchan_cyclic_callback(vd);
+ axi_chan_enable(chan);
} else {
-#endif
/* Remove the completed descriptor from issued list */
list_del(&vd->node);
/* WARN about bad descriptor */
dev_err(chan2dev(chan),
- "Bad descriptor submitted for %s, cookie: %d, irq: 0x%08x\n",
- axi_chan_name(chan), vd->tx.cookie, status);
+ "Bad descriptor submitted for %s, cookie: %d\n",
+ axi_chan_name(chan), vd->tx.cookie);
axi_chan_list_dump_lli(chan, vd_to_axi_desc(vd));
vchan_cookie_complete(vd);
/* Try to restart the controller */
axi_chan_start_first_queued(chan);
-#ifdef CONFIG_DW_AXI_DMAC_STARFIVE
}
-#endif
spin_unlock_irqrestore(&chan->vc.lock, flags);
}
+
+static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&chan->vc.lock, flags);
+ if (unlikely(axi_chan_is_hw_enable(chan))) {
+ axi_chan_disable(chan);
+ }
+ spin_unlock_irqrestore(&chan->vc.lock, flags);
+
+ tasklet_schedule(&chan->dma_tasklet);
+}
+
static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
{
int count = atomic_read(&chan->descs_allocated);
@@ -1127,6 +1054,9 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan)
if (hw_desc->llp == llp) {
axi_chan_irq_clear(chan, hw_desc->lli->status_lo);
hw_desc->lli->ctl_hi |= CH_CTL_H_LLI_VALID;
+ #ifdef CONFIG_SOC_STARFIVE_VIC7100
+ starfive_flush_dcache(hw_desc->llp, sizeof(*hw_desc->lli));
+ #endif
desc->completed_blocks = i;
if (((hw_desc->len * (i + 1)) % desc->period_len) == 0)
@@ -1169,11 +1099,11 @@ static irqreturn_t dw_axi_dma_interrupt(int irq, void *dev_id)
dev_vdbg(chip->dev, "%s %u IRQ status: 0x%08x\n",
axi_chan_name(chan), i, status);
- if (status & DWAXIDMAC_IRQ_ALL_ERR)
+ if (status & DWAXIDMAC_IRQ_ALL_ERR) {
axi_chan_handle_err(chan, status);
+ }
else if (status & DWAXIDMAC_IRQ_DMA_TRF) {
axi_chan_block_xfer_complete(chan);
- dev_dbg(chip->dev, "axi_chan_block_xfer_complete.\n");
}
}
@@ -1200,13 +1130,6 @@ static int dma_chan_terminate_all(struct dma_chan *dchan)
dev_warn(dchan2dev(dchan),
"%s failed to stop\n", axi_chan_name(chan));
-
- if (chan->direction != DMA_MEM_TO_MEM)
- dw_axi_dma_set_hw_channel(chan->chip,
- chan->hw_handshake_num, false);
- if (chan->direction == DMA_MEM_TO_DEV)
- dw_axi_dma_set_byte_halfword(chan, false);
-
spin_lock_irqsave(&chan->vc.lock, flags);
vchan_get_all_descriptors(&chan->vc, &head);
@@ -1367,7 +1290,7 @@ static int parse_device_properties(struct axi_dma_chip *chip)
if(chip->dw->hdata->nr_channels > 8){
chip->flag->nr_chan_8 = true;
-#ifdef CONFIG_DW_AXI_DMAC_STARFIVE
+#ifdef CONFIG_SOC_STARFIVE_VIC7100
chip->flag->need_flush = true;
#endif
}
@@ -1428,7 +1351,6 @@ static int parse_device_properties(struct axi_dma_chip *chip)
static int dw_probe(struct platform_device *pdev)
{
- struct device_node *node = pdev->dev.of_node;
struct axi_dma_chip *chip;
struct resource *mem;
struct dw_axi_dma *dw;
@@ -1467,12 +1389,6 @@ static int dw_probe(struct platform_device *pdev)
if (IS_ERR(chip->regs))
return PTR_ERR(chip->regs);
- if (of_device_is_compatible(node, "intel,kmb-axi-dma")) {
- chip->apb_regs = devm_platform_ioremap_resource(pdev, 1);
- if (IS_ERR(chip->apb_regs))
- return PTR_ERR(chip->apb_regs);
- }
-
chip->core_clk = devm_clk_get(chip->dev, "core-clk");
if (IS_ERR(chip->core_clk))
return PTR_ERR(chip->core_clk);
@@ -1507,6 +1423,8 @@ static int dw_probe(struct platform_device *pdev)
chan->vc.desc_free = vchan_desc_put;
vchan_init(&chan->vc, &dw->dma);
+
+ tasklet_setup(&chan->dma_tasklet, axi_chan_tasklet);
}
/* Set capabilities */
@@ -1544,11 +1462,7 @@ static int dw_probe(struct platform_device *pdev)
* Therefore, set constraint to 1024 * 4.
*/
dw->dma.dev->dma_parms = &dw->dma_parms;
-#ifdef CONFIG_DW_AXI_DMAC_STARFIVE
dma_set_max_seg_size(&pdev->dev, DMAC_MAX_BLK_SIZE);
-#else
- dma_set_max_seg_size(&pdev->dev, MAX_BLOCK_SIZE);
-#endif
platform_set_drvdata(pdev, chip);
pm_runtime_enable(chip->dev);
@@ -1603,6 +1517,7 @@ static int dw_remove(struct platform_device *pdev)
for (i = 0; i < dw->hdata->nr_channels; i++) {
axi_chan_disable(&chip->dw->chan[i]);
axi_chan_irq_disable(&chip->dw->chan[i], DWAXIDMAC_IRQ_ALL);
+ tasklet_kill(&chan->dma_tasklet);
}
axi_dma_disable(chip);
@@ -1628,7 +1543,6 @@ static const struct dev_pm_ops dw_axi_dma_pm_ops = {
static const struct of_device_id dw_dma_of_id_table[] = {
{ .compatible = "snps,axi-dma-1.01a" },
- { .compatible = "intel,kmb-axi-dma" },
{}
};
MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
@@ -1638,7 +1552,7 @@ static struct platform_driver dw_driver = {
.remove = dw_remove,
.driver = {
.name = KBUILD_MODNAME,
- .of_match_table = dw_dma_of_id_table,
+ .of_match_table = of_match_ptr(dw_dma_of_id_table),
.pm = &dw_axi_dma_pm_ops,
},
};
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index f0520a493e31..6715a51aa649 100644..100755
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -59,6 +59,7 @@ struct axi_dma_chan {
bool is_err;
/* these other elements are all protected by vc.lock */
bool is_paused;
+ struct tasklet_struct dma_tasklet;
};
struct dw_axi_dma {
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 9641e0137804..cb795135ffc2 100755
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -41,7 +41,6 @@
* Compatibility
*/
-#define CONFIG_SND_STARFIVE
struct snd_pcm_hw_params_old {
unsigned int flags;
unsigned int masks[SNDRV_PCM_HW_PARAM_SUBFORMAT -
@@ -730,11 +729,6 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
runtime->subformat = params_subformat(params);
runtime->channels = params_channels(params);
runtime->rate = params_rate(params);
-#ifdef CONFIG_SND_STARFIVE
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- runtime->period_size = params_period_size(params)/2;
- else
-#endif
runtime->period_size = params_period_size(params);
runtime->periods = params_periods(params);
runtime->buffer_size = params_buffer_size(params);
diff --git a/sound/soc/starfive/starfive_pwmdac.c b/sound/soc/starfive/starfive_pwmdac.c
index ee1fceb391b5..1c25e1e2701d 100644..100755
--- a/sound/soc/starfive/starfive_pwmdac.c
+++ b/sound/soc/starfive/starfive_pwmdac.c
@@ -61,9 +61,8 @@ static int pwmdac_shift_bit_info(struct snd_kcontrol *kcontrol,
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = items;
- if (uinfo->value.enumerated.item >= items) {
+ if (uinfo->value.enumerated.item >= items)
uinfo->value.enumerated.item = items - 1;
- }
strcpy(uinfo->value.enumerated.name,
pwmdac_ct_shift_bit[uinfo->value.enumerated.item].name);
@@ -150,43 +149,6 @@ static int pwmdac_duty_cycle_put(struct snd_kcontrol *kcontrol,
return 0;
}
-static int pwmdac_datan_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = 1;
- uinfo->value.integer.min = 1;
- uinfo->value.integer.max = PWMDAC_SAMPLE_CNT_511;
- uinfo->value.integer.step = 1;
- return 0;
-}
-
-static int pwmdac_datan_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct sf_pwmdac_dev *dev = snd_soc_component_get_drvdata(component);
-
- ucontrol->value.integer.value[0] = dev->datan;
-
- return 0;
-}
-
-static int pwmdac_datan_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct sf_pwmdac_dev *dev = snd_soc_component_get_drvdata(component);
- int sel = ucontrol->value.integer.value[0];
-
- if (sel > PWMDAC_SAMPLE_CNT_511)
- return 0;
-
- dev->datan = sel;
-
- return 0;
-}
-
static int pwmdac_data_mode_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
@@ -460,9 +422,7 @@ static void pwmdac_set(struct sf_pwmdac_dev *dev)
pwmdac_LR_data_change(dev, dev->lr_change);
pwmdac_data_mode(dev, dev->data_mode);
- if (dev->shift) {
- pwmdac_data_shift(dev, dev->shift);
- }
+ pwmdac_data_shift(dev, dev->shift);
}
static void pwmdac_stop(struct sf_pwmdac_dev *dev)
@@ -526,8 +486,6 @@ static int pwmdac_config(struct sf_pwmdac_dev *dev)
static int sf_pwmdac_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct sf_pwmdac_dev *dev = snd_soc_dai_get_drvdata(dai);
- //pwmdac_set(dev);
return 0;
}
@@ -592,6 +550,35 @@ static int sf_pwmdac_trigger(struct snd_pcm_substream *substream,
return 0;
}
+static int sf_pwmdac_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+ struct sf_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
+
+ dev->play_dma_data.addr = dev->mapbase + PWMDAC_WDATA;
+
+ switch (params_channels(params)) {
+ case 2:
+ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ break;
+ case 1:
+ dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ break;
+ default:
+ dev_err(dai->dev, "%d channels not supported\n",
+ params_channels(params));
+ return -EINVAL;
+ }
+
+ dev->play_dma_data.fifo_size = 1;
+ dev->play_dma_data.maxburst = 16;
+
+ snd_soc_dai_init_dma_data(dai, &dev->play_dma_data, NULL);
+ snd_soc_dai_set_drvdata(dai, dev);
+
+ return 0;
+}
+
static int sf_pwmdac_dai_probe(struct snd_soc_dai *dai)
{
struct sf_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
@@ -624,7 +611,6 @@ static const struct snd_kcontrol_new pwmdac_snd_controls[] = {
};
static int pwmdac_probe(struct snd_soc_component *component)
{
- struct sf_pwmdac_dev *priv = snd_soc_component_get_drvdata(component);
snd_soc_add_component_controls(component, pwmdac_snd_controls,
ARRAY_SIZE(pwmdac_snd_controls));
return 0;
@@ -632,6 +618,7 @@ static int pwmdac_probe(struct snd_soc_component *component)
static const struct snd_soc_dai_ops sf_pwmdac_dai_ops = {
+ .hw_params = sf_pwmdac_hw_params,
.prepare = sf_pwmdac_prepare,
.trigger = sf_pwmdac_trigger,
};