Lines Matching +full:dai +full:- +full:format
1 // SPDX-License-Identifier: GPL-2.0-only
16 * OMAP ALSA SoC DAI driver using McBSP port
21 * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver
23 * Copyright 2007-2010 Freescale Semiconductor, Inc.
130 unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; in bcm2835_i2s_start_clock()
132 if (dev->clk_prepared) in bcm2835_i2s_start_clock()
138 clk_prepare_enable(dev->clk); in bcm2835_i2s_start_clock()
139 dev->clk_prepared = true; in bcm2835_i2s_start_clock()
148 if (dev->clk_prepared) in bcm2835_i2s_stop_clock()
149 clk_disable_unprepare(dev->clk); in bcm2835_i2s_stop_clock()
150 dev->clk_prepared = false; in bcm2835_i2s_stop_clock()
171 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); in bcm2835_i2s_clear_fifos()
175 clk_was_prepared = dev->clk_prepared; in bcm2835_i2s_clear_fifos()
180 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, off, 0); in bcm2835_i2s_clear_fifos()
186 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, clr, clr); in bcm2835_i2s_clear_fifos()
194 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &syncval); in bcm2835_i2s_clear_fifos()
197 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, in bcm2835_i2s_clear_fifos()
201 while (--timeout) { in bcm2835_i2s_clear_fifos()
202 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); in bcm2835_i2s_clear_fifos()
208 dev_err(dev->dev, "I2S SYNC error!\n"); in bcm2835_i2s_clear_fifos()
215 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, in bcm2835_i2s_clear_fifos()
219 static int bcm2835_i2s_set_dai_fmt(struct snd_soc_dai *dai, in bcm2835_i2s_set_dai_fmt() argument
222 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); in bcm2835_i2s_set_dai_fmt()
223 dev->fmt = fmt; in bcm2835_i2s_set_dai_fmt()
227 static int bcm2835_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, in bcm2835_i2s_set_dai_bclk_ratio() argument
230 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); in bcm2835_i2s_set_dai_bclk_ratio()
233 dev->tdm_slots = 0; in bcm2835_i2s_set_dai_bclk_ratio()
238 return -EINVAL; in bcm2835_i2s_set_dai_bclk_ratio()
240 dev->tdm_slots = 2; in bcm2835_i2s_set_dai_bclk_ratio()
241 dev->rx_mask = 0x03; in bcm2835_i2s_set_dai_bclk_ratio()
242 dev->tx_mask = 0x03; in bcm2835_i2s_set_dai_bclk_ratio()
243 dev->slot_width = ratio / 2; in bcm2835_i2s_set_dai_bclk_ratio()
244 dev->frame_length = ratio; in bcm2835_i2s_set_dai_bclk_ratio()
249 static int bcm2835_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai, in bcm2835_i2s_set_dai_tdm_slot() argument
253 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); in bcm2835_i2s_set_dai_tdm_slot()
257 return -EINVAL; in bcm2835_i2s_set_dai_tdm_slot()
260 rx_mask &= GENMASK(slots - 1, 0); in bcm2835_i2s_set_dai_tdm_slot()
261 tx_mask &= GENMASK(slots - 1, 0); in bcm2835_i2s_set_dai_tdm_slot()
264 * The driver is limited to 2-channel setups. in bcm2835_i2s_set_dai_tdm_slot()
269 return -EINVAL; in bcm2835_i2s_set_dai_tdm_slot()
272 return -EINVAL; in bcm2835_i2s_set_dai_tdm_slot()
275 dev->tdm_slots = slots; in bcm2835_i2s_set_dai_tdm_slot()
277 dev->rx_mask = rx_mask; in bcm2835_i2s_set_dai_tdm_slot()
278 dev->tx_mask = tx_mask; in bcm2835_i2s_set_dai_tdm_slot()
279 dev->slot_width = width; in bcm2835_i2s_set_dai_tdm_slot()
280 dev->frame_length = slots * width; in bcm2835_i2s_set_dai_tdm_slot()
315 * I2S-style TDM slot numbering ( 0 2 ... 3 4 ...) with odd
323 *ch1_pos = bcm2835_i2s_convert_slot((ffs(mask) - 1), odd_offset) in bcm2835_i2s_calc_channel_pos()
325 *ch2_pos = bcm2835_i2s_convert_slot((fls(mask) - 1), odd_offset) in bcm2835_i2s_calc_channel_pos()
331 struct snd_soc_dai *dai) in bcm2835_i2s_hw_params() argument
333 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); in bcm2835_i2s_hw_params()
339 unsigned int mode, format; in bcm2835_i2s_hw_params() local
350 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg); in bcm2835_i2s_hw_params()
360 if (dev->tdm_slots) { in bcm2835_i2s_hw_params()
361 slots = dev->tdm_slots; in bcm2835_i2s_hw_params()
362 slot_width = dev->slot_width; in bcm2835_i2s_hw_params()
363 frame_length = dev->frame_length; in bcm2835_i2s_hw_params()
364 rx_mask = dev->rx_mask; in bcm2835_i2s_hw_params()
365 tx_mask = dev->tx_mask; in bcm2835_i2s_hw_params()
366 bclk_rate = dev->frame_length * params_rate(params); in bcm2835_i2s_hw_params()
384 return -EINVAL; in bcm2835_i2s_hw_params()
387 switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { in bcm2835_i2s_hw_params()
397 return -EINVAL; in bcm2835_i2s_hw_params()
401 switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { in bcm2835_i2s_hw_params()
411 return -EINVAL; in bcm2835_i2s_hw_params()
416 (!dev->clk_prepared || dev->clk_rate != bclk_rate)) { in bcm2835_i2s_hw_params()
417 if (dev->clk_prepared) in bcm2835_i2s_hw_params()
420 if (dev->clk_rate != bclk_rate) { in bcm2835_i2s_hw_params()
421 ret = clk_set_rate(dev->clk, bclk_rate); in bcm2835_i2s_hw_params()
424 dev->clk_rate = bclk_rate; in bcm2835_i2s_hw_params()
430 /* Setup the frame format */ in bcm2835_i2s_hw_params()
431 format = BCM2835_I2S_CHEN; in bcm2835_i2s_hw_params()
434 format |= BCM2835_I2S_CHWEX; in bcm2835_i2s_hw_params()
436 format |= BCM2835_I2S_CHWID((data_length-8)&0xf); in bcm2835_i2s_hw_params()
438 /* CH2 format is the same as for CH1 */ in bcm2835_i2s_hw_params()
439 format = BCM2835_I2S_CH1(format) | BCM2835_I2S_CH2(format); in bcm2835_i2s_hw_params()
441 switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { in bcm2835_i2s_hw_params()
445 return -EINVAL; in bcm2835_i2s_hw_params()
448 * Use I2S-style logical slot numbering: even slots in bcm2835_i2s_hw_params()
462 return -EINVAL; in bcm2835_i2s_hw_params()
471 return -EINVAL; in bcm2835_i2s_hw_params()
475 return -EINVAL; in bcm2835_i2s_hw_params()
478 data_delay = slot_width - data_length; in bcm2835_i2s_hw_params()
493 return -EINVAL; in bcm2835_i2s_hw_params()
503 * in left-justified or DSP mode A, only works stable in bcm2835_i2s_hw_params()
507 dev_warn(dev->dev, in bcm2835_i2s_hw_params()
511 * Set format for both streams. in bcm2835_i2s_hw_params()
514 * so the format will be the same. in bcm2835_i2s_hw_params()
516 regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, in bcm2835_i2s_hw_params()
517 format in bcm2835_i2s_hw_params()
520 regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, in bcm2835_i2s_hw_params()
521 format in bcm2835_i2s_hw_params()
532 * so the format will be the same. in bcm2835_i2s_hw_params()
537 mode |= BCM2835_I2S_FLEN(frame_length - 1); in bcm2835_i2s_hw_params()
549 switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) { in bcm2835_i2s_hw_params()
558 return -EINVAL; in bcm2835_i2s_hw_params()
562 switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) { in bcm2835_i2s_hw_params()
574 return -EINVAL; in bcm2835_i2s_hw_params()
577 regmap_write(dev->i2s_regmap, BCM2835_I2S_MODE_A_REG, mode); in bcm2835_i2s_hw_params()
580 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, in bcm2835_i2s_hw_params()
585 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG, in bcm2835_i2s_hw_params()
594 dev_dbg(dev->dev, in bcm2835_i2s_hw_params()
598 dev_dbg(dev->dev, "frame len: %d sync len: %d data len: %d\n", in bcm2835_i2s_hw_params()
601 dev_dbg(dev->dev, "rx pos: %d,%d tx pos: %d,%d\n", in bcm2835_i2s_hw_params()
604 dev_dbg(dev->dev, "sampling rate: %d bclk rate: %d\n", in bcm2835_i2s_hw_params()
607 dev_dbg(dev->dev, "CLKM: %d CLKI: %d FSM: %d FSI: %d frame start: %s edge\n", in bcm2835_i2s_hw_params()
618 struct snd_soc_dai *dai) in bcm2835_i2s_prepare() argument
620 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); in bcm2835_i2s_prepare()
629 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &cs_reg); in bcm2835_i2s_prepare()
631 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK in bcm2835_i2s_prepare()
634 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE in bcm2835_i2s_prepare()
643 struct snd_soc_dai *dai) in bcm2835_i2s_stop() argument
647 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) in bcm2835_i2s_stop()
652 regmap_update_bits(dev->i2s_regmap, in bcm2835_i2s_stop()
656 if (!snd_soc_dai_active(dai) && !(dev->fmt & SND_SOC_DAIFMT_CONT)) in bcm2835_i2s_stop()
661 struct snd_soc_dai *dai) in bcm2835_i2s_trigger() argument
663 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); in bcm2835_i2s_trigger()
672 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) in bcm2835_i2s_trigger()
677 regmap_update_bits(dev->i2s_regmap, in bcm2835_i2s_trigger()
684 bcm2835_i2s_stop(dev, substream, dai); in bcm2835_i2s_trigger()
687 return -EINVAL; in bcm2835_i2s_trigger()
694 struct snd_soc_dai *dai) in bcm2835_i2s_startup() argument
696 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); in bcm2835_i2s_startup()
698 if (snd_soc_dai_active(dai)) in bcm2835_i2s_startup()
705 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, in bcm2835_i2s_startup()
712 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, in bcm2835_i2s_startup()
719 struct snd_soc_dai *dai) in bcm2835_i2s_shutdown() argument
721 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); in bcm2835_i2s_shutdown()
723 bcm2835_i2s_stop(dev, substream, dai); in bcm2835_i2s_shutdown()
726 if (snd_soc_dai_active(dai)) in bcm2835_i2s_shutdown()
730 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, in bcm2835_i2s_shutdown()
751 static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai) in bcm2835_i2s_dai_probe() argument
753 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); in bcm2835_i2s_dai_probe()
755 snd_soc_dai_init_dma_data(dai, in bcm2835_i2s_dai_probe()
756 &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK], in bcm2835_i2s_dai_probe()
757 &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]); in bcm2835_i2s_dai_probe()
763 .name = "bcm2835-i2s",
824 .name = "bcm2835-i2s-comp",
835 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), in bcm2835_i2s_probe()
838 return -ENOMEM; in bcm2835_i2s_probe()
841 dev->clk_prepared = false; in bcm2835_i2s_probe()
842 dev->clk = devm_clk_get(&pdev->dev, NULL); in bcm2835_i2s_probe()
843 if (IS_ERR(dev->clk)) { in bcm2835_i2s_probe()
844 ret = PTR_ERR(dev->clk); in bcm2835_i2s_probe()
845 if (ret == -EPROBE_DEFER) in bcm2835_i2s_probe()
846 dev_dbg(&pdev->dev, "could not get clk: %d\n", ret); in bcm2835_i2s_probe()
848 dev_err(&pdev->dev, "could not get clk: %d\n", ret); in bcm2835_i2s_probe()
857 dev->i2s_regmap = devm_regmap_init_mmio(&pdev->dev, base, in bcm2835_i2s_probe()
859 if (IS_ERR(dev->i2s_regmap)) in bcm2835_i2s_probe()
860 return PTR_ERR(dev->i2s_regmap); in bcm2835_i2s_probe()
862 /* Set the DMA address - we have to parse DT ourselves */ in bcm2835_i2s_probe()
863 addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL); in bcm2835_i2s_probe()
865 dev_err(&pdev->dev, "could not get DMA-register address\n"); in bcm2835_i2s_probe()
866 return -EINVAL; in bcm2835_i2s_probe()
870 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = in bcm2835_i2s_probe()
873 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = in bcm2835_i2s_probe()
877 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = in bcm2835_i2s_probe()
879 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width = in bcm2835_i2s_probe()
883 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2; in bcm2835_i2s_probe()
884 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2; in bcm2835_i2s_probe()
888 * packed into 32-bit transfers). in bcm2835_i2s_probe()
890 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].flags = in bcm2835_i2s_probe()
892 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].flags = in bcm2835_i2s_probe()
896 dev->dev = &pdev->dev; in bcm2835_i2s_probe()
897 dev_set_drvdata(&pdev->dev, dev); in bcm2835_i2s_probe()
899 ret = devm_snd_soc_register_component(&pdev->dev, in bcm2835_i2s_probe()
902 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); in bcm2835_i2s_probe()
906 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); in bcm2835_i2s_probe()
908 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); in bcm2835_i2s_probe()
916 { .compatible = "brcm,bcm2835-i2s", },
925 .name = "bcm2835-i2s",
932 MODULE_ALIAS("platform:bcm2835-i2s");