Lines Matching +full:chip +full:- +full:id
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
21 #include <sound/soc-dai.h>
22 #include <linux/dma-mapping.h>
34 static inline void acp_set_i2s_clk(struct acp_chip_info *chip, int dai_id) in acp_set_i2s_clk() argument
54 if (chip->tdm_mode) in acp_set_i2s_clk()
57 switch (chip->acp_rev) { in acp_set_i2s_clk()
62 val |= FIELD_PREP(ACP63_LRCLK_DIV_FIELD, chip->lrclk_div); in acp_set_i2s_clk()
63 val |= FIELD_PREP(ACP63_BCLK_DIV_FIELD, chip->bclk_div); in acp_set_i2s_clk()
66 val |= FIELD_PREP(LRCLK_DIV_FIELD, chip->lrclk_div); in acp_set_i2s_clk()
67 val |= FIELD_PREP(BCLK_DIV_FIELD, chip->bclk_div); in acp_set_i2s_clk()
69 writel(val, chip->base + i2s_clk_reg); in acp_set_i2s_clk()
75 struct device *dev = cpu_dai->component->dev; in acp_i2s_set_fmt()
76 struct acp_chip_info *chip = dev_get_drvdata(dev->parent); in acp_i2s_set_fmt() local
82 chip->tdm_mode = TDM_DISABLE; in acp_i2s_set_fmt()
85 chip->tdm_mode = TDM_ENABLE; in acp_i2s_set_fmt()
88 return -EINVAL; in acp_i2s_set_fmt()
96 struct device *dev = dai->component->dev; in acp_i2s_set_tdm_slot()
97 struct acp_chip_info *chip; in acp_i2s_set_tdm_slot() local
101 chip = dev_get_drvdata(dev->parent); in acp_i2s_set_tdm_slot()
117 return -EINVAL; in acp_i2s_set_tdm_slot()
120 switch (chip->acp_rev) { in acp_i2s_set_tdm_slot()
132 return -EINVAL; in acp_i2s_set_tdm_slot()
148 return -EINVAL; in acp_i2s_set_tdm_slot()
152 dev_err(dev, "Unknown chip revision %d\n", chip->acp_rev); in acp_i2s_set_tdm_slot()
153 return -EINVAL; in acp_i2s_set_tdm_slot()
158 spin_lock_irq(&chip->acp_lock); in acp_i2s_set_tdm_slot()
159 list_for_each_entry(stream, &chip->stream_list, list) { in acp_i2s_set_tdm_slot()
160 switch (chip->acp_rev) { in acp_i2s_set_tdm_slot()
163 if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK) in acp_i2s_set_tdm_slot()
164 chip->tdm_tx_fmt[stream->dai_id - 1] = in acp_i2s_set_tdm_slot()
166 else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE) in acp_i2s_set_tdm_slot()
167 chip->tdm_rx_fmt[stream->dai_id - 1] = in acp_i2s_set_tdm_slot()
174 if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK) in acp_i2s_set_tdm_slot()
175 chip->tdm_tx_fmt[stream->dai_id - 1] = in acp_i2s_set_tdm_slot()
177 else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE) in acp_i2s_set_tdm_slot()
178 chip->tdm_rx_fmt[stream->dai_id - 1] = in acp_i2s_set_tdm_slot()
182 dev_err(dev, "Unknown chip revision %d\n", chip->acp_rev); in acp_i2s_set_tdm_slot()
183 spin_unlock_irq(&chip->acp_lock); in acp_i2s_set_tdm_slot()
184 return -EINVAL; in acp_i2s_set_tdm_slot()
187 spin_unlock_irq(&chip->acp_lock); in acp_i2s_set_tdm_slot()
194 struct device *dev = dai->component->dev; in acp_i2s_hwparams()
195 struct acp_chip_info *chip; in acp_i2s_hwparams() local
202 chip = dev_get_drvdata(dev->parent); in acp_i2s_hwparams()
203 rsrc = chip->rsrc; in acp_i2s_hwparams()
221 return -EINVAL; in acp_i2s_hwparams()
224 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in acp_i2s_hwparams()
225 switch (dai->driver->id) { in acp_i2s_hwparams()
239 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); in acp_i2s_hwparams()
240 return -EINVAL; in acp_i2s_hwparams()
242 chip->xfer_tx_resolution[dai->driver->id - 1] = xfer_resolution; in acp_i2s_hwparams()
244 switch (dai->driver->id) { in acp_i2s_hwparams()
258 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); in acp_i2s_hwparams()
259 return -EINVAL; in acp_i2s_hwparams()
261 chip->xfer_rx_resolution[dai->driver->id - 1] = xfer_resolution; in acp_i2s_hwparams()
264 val = readl(chip->base + reg_val); in acp_i2s_hwparams()
267 writel(val, chip->base + reg_val); in acp_i2s_hwparams()
269 if (chip->tdm_mode) { in acp_i2s_hwparams()
270 val = readl(chip->base + reg_val); in acp_i2s_hwparams()
271 writel(val | BIT(1), chip->base + reg_val); in acp_i2s_hwparams()
272 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in acp_i2s_hwparams()
273 tdm_fmt = chip->tdm_tx_fmt[dai->driver->id - 1]; in acp_i2s_hwparams()
275 tdm_fmt = chip->tdm_rx_fmt[dai->driver->id - 1]; in acp_i2s_hwparams()
276 writel(tdm_fmt, chip->base + fmt_reg); in acp_i2s_hwparams()
279 if (rsrc->soc_mclk) { in acp_i2s_hwparams()
307 return -EINVAL; in acp_i2s_hwparams()
337 return -EINVAL; in acp_i2s_hwparams()
342 return -EINVAL; in acp_i2s_hwparams()
379 chip->lrclk_div = lrclk_div_val; in acp_i2s_hwparams()
380 chip->bclk_div = bclk_div_val; in acp_i2s_hwparams()
387 struct acp_stream *stream = substream->runtime->private_data; in acp_i2s_trigger()
388 struct device *dev = dai->component->dev; in acp_i2s_trigger()
389 struct acp_chip_info *chip = dev_get_drvdata(dev->parent); in acp_i2s_trigger() local
390 struct acp_resource *rsrc = chip->rsrc; in acp_i2s_trigger()
393 period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size); in acp_i2s_trigger()
394 buf_size = frames_to_bytes(substream->runtime, substream->runtime->buffer_size); in acp_i2s_trigger()
400 stream->bytescount = acp_get_byte_count(chip, stream->dai_id, substream->stream); in acp_i2s_trigger()
401 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in acp_i2s_trigger()
402 switch (dai->driver->id) { in acp_i2s_trigger()
404 water_val = ACP_BT_TX_INTR_WATERMARK_SIZE(chip); in acp_i2s_trigger()
407 buf_reg = ACP_BT_TX_RINGBUFSIZE(chip); in acp_i2s_trigger()
410 water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE(chip); in acp_i2s_trigger()
413 buf_reg = ACP_I2S_TX_RINGBUFSIZE(chip); in acp_i2s_trigger()
422 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); in acp_i2s_trigger()
423 return -EINVAL; in acp_i2s_trigger()
426 switch (dai->driver->id) { in acp_i2s_trigger()
428 water_val = ACP_BT_RX_INTR_WATERMARK_SIZE(chip); in acp_i2s_trigger()
431 buf_reg = ACP_BT_RX_RINGBUFSIZE(chip); in acp_i2s_trigger()
434 water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE(chip); in acp_i2s_trigger()
437 buf_reg = ACP_I2S_RX_RINGBUFSIZE(chip); in acp_i2s_trigger()
446 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); in acp_i2s_trigger()
447 return -EINVAL; in acp_i2s_trigger()
451 writel(period_bytes, chip->base + water_val); in acp_i2s_trigger()
452 writel(buf_size, chip->base + buf_reg); in acp_i2s_trigger()
453 if (rsrc->soc_mclk) in acp_i2s_trigger()
454 acp_set_i2s_clk(chip, dai->driver->id); in acp_i2s_trigger()
455 val = readl(chip->base + reg_val); in acp_i2s_trigger()
457 writel(val, chip->base + reg_val); in acp_i2s_trigger()
458 writel(1, chip->base + ier_val); in acp_i2s_trigger()
463 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in acp_i2s_trigger()
464 switch (dai->driver->id) { in acp_i2s_trigger()
475 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); in acp_i2s_trigger()
476 return -EINVAL; in acp_i2s_trigger()
480 switch (dai->driver->id) { in acp_i2s_trigger()
491 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); in acp_i2s_trigger()
492 return -EINVAL; in acp_i2s_trigger()
495 val = readl(chip->base + reg_val); in acp_i2s_trigger()
497 writel(val, chip->base + reg_val); in acp_i2s_trigger()
499 if (!(readl(chip->base + ACP_BTTDM_ITER) & BIT(0)) && in acp_i2s_trigger()
500 !(readl(chip->base + ACP_BTTDM_IRER) & BIT(0))) in acp_i2s_trigger()
501 writel(0, chip->base + ACP_BTTDM_IER); in acp_i2s_trigger()
502 if (!(readl(chip->base + ACP_I2STDM_ITER) & BIT(0)) && in acp_i2s_trigger()
503 !(readl(chip->base + ACP_I2STDM_IRER) & BIT(0))) in acp_i2s_trigger()
504 writel(0, chip->base + ACP_I2STDM_IER); in acp_i2s_trigger()
505 if (!(readl(chip->base + ACP_HSTDM_ITER) & BIT(0)) && in acp_i2s_trigger()
506 !(readl(chip->base + ACP_HSTDM_IRER) & BIT(0))) in acp_i2s_trigger()
507 writel(0, chip->base + ACP_HSTDM_IER); in acp_i2s_trigger()
510 return -EINVAL; in acp_i2s_trigger()
518 struct device *dev = dai->component->dev; in acp_i2s_prepare()
519 struct acp_chip_info *chip = dev_get_drvdata(dev->parent); in acp_i2s_prepare() local
520 struct acp_resource *rsrc = chip->rsrc; in acp_i2s_prepare()
521 struct acp_stream *stream = substream->runtime->private_data; in acp_i2s_prepare()
524 unsigned int dir = substream->stream; in acp_i2s_prepare()
526 switch (dai->driver->id) { in acp_i2s_prepare()
529 reg_dma_size = ACP_I2S_TX_DMA_SIZE(chip); in acp_i2s_prepare()
530 acp_fifo_addr = rsrc->sram_pte_offset + in acp_i2s_prepare()
532 reg_fifo_addr = ACP_I2S_TX_FIFOADDR(chip); in acp_i2s_prepare()
533 reg_fifo_size = ACP_I2S_TX_FIFOSIZE(chip); in acp_i2s_prepare()
535 if (chip->acp_rev >= ACP70_PCI_ID) in acp_i2s_prepare()
538 phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset; in acp_i2s_prepare()
539 writel(phy_addr, chip->base + ACP_I2S_TX_RINGBUFADDR(chip)); in acp_i2s_prepare()
541 reg_dma_size = ACP_I2S_RX_DMA_SIZE(chip); in acp_i2s_prepare()
542 acp_fifo_addr = rsrc->sram_pte_offset + in acp_i2s_prepare()
544 reg_fifo_addr = ACP_I2S_RX_FIFOADDR(chip); in acp_i2s_prepare()
545 reg_fifo_size = ACP_I2S_RX_FIFOSIZE(chip); in acp_i2s_prepare()
547 if (chip->acp_rev >= ACP70_PCI_ID) in acp_i2s_prepare()
550 phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset; in acp_i2s_prepare()
551 writel(phy_addr, chip->base + ACP_I2S_RX_RINGBUFADDR(chip)); in acp_i2s_prepare()
556 reg_dma_size = ACP_BT_TX_DMA_SIZE(chip); in acp_i2s_prepare()
557 acp_fifo_addr = rsrc->sram_pte_offset + in acp_i2s_prepare()
559 reg_fifo_addr = ACP_BT_TX_FIFOADDR(chip); in acp_i2s_prepare()
560 reg_fifo_size = ACP_BT_TX_FIFOSIZE(chip); in acp_i2s_prepare()
562 if (chip->acp_rev >= ACP70_PCI_ID) in acp_i2s_prepare()
565 phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; in acp_i2s_prepare()
566 writel(phy_addr, chip->base + ACP_BT_TX_RINGBUFADDR(chip)); in acp_i2s_prepare()
568 reg_dma_size = ACP_BT_RX_DMA_SIZE(chip); in acp_i2s_prepare()
569 acp_fifo_addr = rsrc->sram_pte_offset + in acp_i2s_prepare()
571 reg_fifo_addr = ACP_BT_RX_FIFOADDR(chip); in acp_i2s_prepare()
572 reg_fifo_size = ACP_BT_RX_FIFOSIZE(chip); in acp_i2s_prepare()
574 if (chip->acp_rev >= ACP70_PCI_ID) in acp_i2s_prepare()
577 phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; in acp_i2s_prepare()
578 writel(phy_addr, chip->base + ACP_BT_RX_RINGBUFADDR(chip)); in acp_i2s_prepare()
584 acp_fifo_addr = rsrc->sram_pte_offset + in acp_i2s_prepare()
589 if (chip->acp_rev >= ACP70_PCI_ID) in acp_i2s_prepare()
592 phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset; in acp_i2s_prepare()
593 writel(phy_addr, chip->base + ACP_HS_TX_RINGBUFADDR); in acp_i2s_prepare()
596 acp_fifo_addr = rsrc->sram_pte_offset + in acp_i2s_prepare()
601 if (chip->acp_rev >= ACP70_PCI_ID) in acp_i2s_prepare()
604 phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset; in acp_i2s_prepare()
605 writel(phy_addr, chip->base + ACP_HS_RX_RINGBUFADDR); in acp_i2s_prepare()
609 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); in acp_i2s_prepare()
610 return -EINVAL; in acp_i2s_prepare()
613 writel(DMA_SIZE, chip->base + reg_dma_size); in acp_i2s_prepare()
614 writel(acp_fifo_addr, chip->base + reg_fifo_addr); in acp_i2s_prepare()
615 writel(FIFO_SIZE, chip->base + reg_fifo_size); in acp_i2s_prepare()
617 ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); in acp_i2s_prepare()
618 ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | in acp_i2s_prepare()
619 BIT(BT_RX_THRESHOLD(rsrc->offset)) | in acp_i2s_prepare()
620 BIT(I2S_TX_THRESHOLD(rsrc->offset)) | in acp_i2s_prepare()
621 BIT(BT_TX_THRESHOLD(rsrc->offset)) | in acp_i2s_prepare()
622 BIT(HS_RX_THRESHOLD(rsrc->offset)) | in acp_i2s_prepare()
623 BIT(HS_TX_THRESHOLD(rsrc->offset)); in acp_i2s_prepare()
625 writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); in acp_i2s_prepare()
632 struct acp_stream *stream = substream->runtime->private_data; in acp_i2s_startup()
633 struct device *dev = dai->component->dev; in acp_i2s_startup()
634 struct acp_chip_info *chip = dev_get_drvdata(dev->parent); in acp_i2s_startup() local
635 struct acp_resource *rsrc = chip->rsrc; in acp_i2s_startup()
636 unsigned int dir = substream->stream; in acp_i2s_startup()
639 switch (dai->driver->id) { in acp_i2s_startup()
642 irq_bit = BIT(I2S_TX_THRESHOLD(rsrc->offset)); in acp_i2s_startup()
643 stream->pte_offset = ACP_SRAM_SP_PB_PTE_OFFSET; in acp_i2s_startup()
644 stream->fifo_offset = SP_PB_FIFO_ADDR_OFFSET; in acp_i2s_startup()
646 irq_bit = BIT(I2S_RX_THRESHOLD(rsrc->offset)); in acp_i2s_startup()
647 stream->pte_offset = ACP_SRAM_SP_CP_PTE_OFFSET; in acp_i2s_startup()
648 stream->fifo_offset = SP_CAPT_FIFO_ADDR_OFFSET; in acp_i2s_startup()
653 irq_bit = BIT(BT_TX_THRESHOLD(rsrc->offset)); in acp_i2s_startup()
654 stream->pte_offset = ACP_SRAM_BT_PB_PTE_OFFSET; in acp_i2s_startup()
655 stream->fifo_offset = BT_PB_FIFO_ADDR_OFFSET; in acp_i2s_startup()
657 irq_bit = BIT(BT_RX_THRESHOLD(rsrc->offset)); in acp_i2s_startup()
658 stream->pte_offset = ACP_SRAM_BT_CP_PTE_OFFSET; in acp_i2s_startup()
659 stream->fifo_offset = BT_CAPT_FIFO_ADDR_OFFSET; in acp_i2s_startup()
664 irq_bit = BIT(HS_TX_THRESHOLD(rsrc->offset)); in acp_i2s_startup()
665 stream->pte_offset = ACP_SRAM_HS_PB_PTE_OFFSET; in acp_i2s_startup()
666 stream->fifo_offset = HS_PB_FIFO_ADDR_OFFSET; in acp_i2s_startup()
668 irq_bit = BIT(HS_RX_THRESHOLD(rsrc->offset)); in acp_i2s_startup()
669 stream->pte_offset = ACP_SRAM_HS_CP_PTE_OFFSET; in acp_i2s_startup()
670 stream->fifo_offset = HS_CAPT_FIFO_ADDR_OFFSET; in acp_i2s_startup()
674 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); in acp_i2s_startup()
675 return -EINVAL; in acp_i2s_startup()
679 stream->id = dai->driver->id + dir; in acp_i2s_startup()
680 stream->dai_id = dai->driver->id; in acp_i2s_startup()
681 stream->irq_bit = irq_bit; in acp_i2s_startup()
682 stream->dir = substream->stream; in acp_i2s_startup()