Lines Matching +full:odd +full:- +full:numbered

1 // SPDX-License-Identifier: GPL-2.0-only
23 * Copyright 2007-2010 Freescale Semiconductor, Inc.
130 unsigned int provider = dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_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()
223 dev->fmt = fmt; in bcm2835_i2s_set_dai_fmt()
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()
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()
291 * Otherwise odd_offset defines the physical offset for odd numbered
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()
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_CLOCK_PROVIDER_MASK) { in bcm2835_i2s_hw_params()
397 return -EINVAL; in bcm2835_i2s_hw_params()
401 switch (dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_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()
436 format |= BCM2835_I2S_CHWID((data_length-8)&0xf); 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()
449 * are in first half of frame, odd slots in second half. in bcm2835_i2s_hw_params()
462 return -EINVAL; in bcm2835_i2s_hw_params()
471 return -EINVAL; in bcm2835_i2s_hw_params()
473 /* Odd frame lengths aren't supported */ 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()
516 regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, in bcm2835_i2s_hw_params()
520 regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, 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()
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()
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()
672 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) in bcm2835_i2s_trigger()
677 regmap_update_bits(dev->i2s_regmap, in bcm2835_i2s_trigger()
687 return -EINVAL; in bcm2835_i2s_trigger()
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()
730 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, in bcm2835_i2s_shutdown()
745 &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK], in bcm2835_i2s_dai_probe()
746 &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]); in bcm2835_i2s_dai_probe()
764 .name = "bcm2835-i2s",
824 .name = "bcm2835-i2s-comp",
836 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), in bcm2835_i2s_probe()
839 return -ENOMEM; in bcm2835_i2s_probe()
842 dev->clk_prepared = false; in bcm2835_i2s_probe()
843 dev->clk = devm_clk_get(&pdev->dev, NULL); in bcm2835_i2s_probe()
844 if (IS_ERR(dev->clk)) in bcm2835_i2s_probe()
845 return dev_err_probe(&pdev->dev, PTR_ERR(dev->clk), in bcm2835_i2s_probe()
853 dev->i2s_regmap = devm_regmap_init_mmio(&pdev->dev, base, in bcm2835_i2s_probe()
855 if (IS_ERR(dev->i2s_regmap)) in bcm2835_i2s_probe()
856 return PTR_ERR(dev->i2s_regmap); in bcm2835_i2s_probe()
858 /* Set the DMA address - we have to parse DT ourselves */ in bcm2835_i2s_probe()
859 addr = of_get_address(pdev->dev.of_node, 0, NULL, NULL); in bcm2835_i2s_probe()
861 dev_err(&pdev->dev, "could not get DMA-register address\n"); in bcm2835_i2s_probe()
862 return -EINVAL; in bcm2835_i2s_probe()
866 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = in bcm2835_i2s_probe()
869 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = in bcm2835_i2s_probe()
873 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = in bcm2835_i2s_probe()
875 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width = in bcm2835_i2s_probe()
879 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2; in bcm2835_i2s_probe()
880 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2; in bcm2835_i2s_probe()
884 * packed into 32-bit transfers). in bcm2835_i2s_probe()
886 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].flags = in bcm2835_i2s_probe()
888 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].flags = in bcm2835_i2s_probe()
892 dev->dev = &pdev->dev; in bcm2835_i2s_probe()
893 dev_set_drvdata(&pdev->dev, dev); in bcm2835_i2s_probe()
895 ret = devm_snd_soc_register_component(&pdev->dev, in bcm2835_i2s_probe()
898 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); in bcm2835_i2s_probe()
902 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); in bcm2835_i2s_probe()
904 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); in bcm2835_i2s_probe()
912 { .compatible = "brcm,bcm2835-i2s", },
921 .name = "bcm2835-i2s",
928 MODULE_ALIAS("platform:bcm2835-i2s");