Lines Matching +full:rx +full:- +full:slots

1 // SPDX-License-Identifier: GPL-2.0
7 // Copyright 2007-2010 Freescale Semiconductor, Inc.
9 // Some notes why imx-pcm-fiq is used instead of DMA on some boards:
13 // one FIFO which combines all valid receive slots. We cannot even select
14 // which slots we want to receive. The WM9712 with which this driver
16 // we receive in our (PCM-) data stream. The only chance we have is to
43 #include <linux/dma/imx-dma.h>
53 #include "imx-pcm.h"
55 /* Define RX and TX to index ssi->regvals array; Can be 0 or 1 only */
56 #define RX 0 macro
66 * (bit-endianness must match byte-endianness). Processors typically write
68 * written in. So if the host CPU is big-endian, then only big-endian
91 * - SSI inputs external bit clock and outputs frame sync clock -- CBM_CFS
92 * - Also have NB_NF to mark these two clocks will not be inverted
201 bool imx21regs; /* imx21-class SSI - no SACC{ST,EN,DIS} regs */
207 * struct fsl_ssi - per-SSI private data
212 * @streams: Mask of current active streams: BIT(TX) and BIT(RX)
215 * @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK
222 * @slots: Number of slots
223 * @regvals: Specific RX/TX register settings
225 * @baudclk: Clock source to generate bit and frame-sync clocks
241 * @dev: Pointer to &pdev->dev
244 * @fifo_watermark or more empty words in RX fifo.
265 unsigned int slots; member
302 * cannot be changed after SSI starts running -- a software reset
344 { .compatible = "fsl,mpc8610-ssi", .data = &fsl_ssi_mpc8610 },
345 { .compatible = "fsl,imx51-ssi", .data = &fsl_ssi_imx51 },
346 { .compatible = "fsl,imx35-ssi", .data = &fsl_ssi_imx35 },
347 { .compatible = "fsl,imx21-ssi", .data = &fsl_ssi_imx21 },
354 return (ssi->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) == in fsl_ssi_is_ac97()
360 return (ssi->dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) == in fsl_ssi_is_i2s_clock_provider()
366 return (ssi->dai_fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) == in fsl_ssi_is_i2s_bc_fp()
371 * fsl_ssi_isr - Interrupt handler to gather states
378 struct regmap *regs = ssi->regs; in fsl_ssi_isr()
383 sisr2 = sisr & ssi->soc->sisr_write_mask; in fsl_ssi_isr()
388 fsl_ssi_dbg_isr(&ssi->dbg_stats, sisr); in fsl_ssi_isr()
394 * fsl_ssi_config_enable - Set SCR, SIER, STCR and SRCR registers with
406 struct fsl_ssi_regvals *vals = ssi->regvals; in fsl_ssi_config_enable()
407 int dir = tx ? TX : RX; in fsl_ssi_config_enable()
411 regmap_update_bits(ssi->regs, REG_SSI_SOR, in fsl_ssi_config_enable()
419 if (ssi->soc->offline_config && ssi->streams) in fsl_ssi_config_enable()
422 if (ssi->soc->offline_config) { in fsl_ssi_config_enable()
427 srcr = vals[RX].srcr | vals[TX].srcr; in fsl_ssi_config_enable()
428 stcr = vals[RX].stcr | vals[TX].stcr; in fsl_ssi_config_enable()
429 sier = vals[RX].sier | vals[TX].sier; in fsl_ssi_config_enable()
438 regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, srcr); in fsl_ssi_config_enable()
439 regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, stcr); in fsl_ssi_config_enable()
440 regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, sier); in fsl_ssi_config_enable()
449 if (ssi->use_dma && tx) { in fsl_ssi_config_enable()
454 regmap_update_bits(ssi->regs, REG_SSI_SCR, in fsl_ssi_config_enable()
457 /* Busy wait until TX FIFO not empty -- DMA working */ in fsl_ssi_config_enable()
459 regmap_read(ssi->regs, REG_SSI_SFCSR, &sfcsr); in fsl_ssi_config_enable()
462 } while (--try); in fsl_ssi_config_enable()
464 /* FIFO still empty -- something might be wrong */ in fsl_ssi_config_enable()
466 dev_warn(ssi->dev, "Timeout waiting TX FIFO filling\n"); in fsl_ssi_config_enable()
469 regmap_update_bits(ssi->regs, REG_SSI_SCR, in fsl_ssi_config_enable()
473 ssi->streams |= BIT(dir); in fsl_ssi_config_enable()
497 * fsl_ssi_config_disable - Unset SCR, SIER, STCR and SRCR registers
511 int adir = tx ? RX : TX; in fsl_ssi_config_disable()
512 int dir = tx ? TX : RX; in fsl_ssi_config_disable()
516 aactive = ssi->streams & BIT(adir); in fsl_ssi_config_disable()
518 vals = &ssi->regvals[dir]; in fsl_ssi_config_disable()
521 avals = &ssi->regvals[adir]; in fsl_ssi_config_disable()
527 scr = ssi_excl_shared_bits(vals->scr, avals->scr, aactive); in fsl_ssi_config_disable()
530 regmap_update_bits(ssi->regs, REG_SSI_SCR, scr, 0); in fsl_ssi_config_disable()
533 ssi->streams &= ~BIT(dir); in fsl_ssi_config_disable()
539 if (ssi->soc->offline_config && aactive) in fsl_ssi_config_disable()
542 if (ssi->soc->offline_config) { in fsl_ssi_config_disable()
544 srcr = vals->srcr | avals->srcr; in fsl_ssi_config_disable()
545 stcr = vals->stcr | avals->stcr; in fsl_ssi_config_disable()
546 sier = vals->sier | avals->sier; in fsl_ssi_config_disable()
552 sier = ssi_excl_shared_bits(vals->sier, avals->sier, aactive); in fsl_ssi_config_disable()
553 srcr = ssi_excl_shared_bits(vals->srcr, avals->srcr, aactive); in fsl_ssi_config_disable()
554 stcr = ssi_excl_shared_bits(vals->stcr, avals->stcr, aactive); in fsl_ssi_config_disable()
558 regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, 0); in fsl_ssi_config_disable()
559 regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, 0); in fsl_ssi_config_disable()
560 regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, 0); in fsl_ssi_config_disable()
564 regmap_update_bits(ssi->regs, REG_SSI_SOR, in fsl_ssi_config_disable()
570 struct regmap *regs = ssi->regs; in fsl_ssi_tx_ac97_saccst_setup()
572 /* no SACC{ST,EN,DIS} regs on imx21-class SSI */ in fsl_ssi_tx_ac97_saccst_setup()
573 if (!ssi->soc->imx21regs) { in fsl_ssi_tx_ac97_saccst_setup()
574 /* Disable all channel slots */ in fsl_ssi_tx_ac97_saccst_setup()
576 /* Enable slots 3 & 4 -- PCM Playback Left & Right channels */ in fsl_ssi_tx_ac97_saccst_setup()
582 * fsl_ssi_setup_regvals - Cache critical bits of SIER, SRCR, STCR and
588 struct fsl_ssi_regvals *vals = ssi->regvals; in fsl_ssi_setup_regvals()
590 vals[RX].sier = SSI_SIER_RFF0_EN | FSLSSI_SIER_DBG_RX_FLAGS; in fsl_ssi_setup_regvals()
591 vals[RX].srcr = SSI_SRCR_RFEN0; in fsl_ssi_setup_regvals()
592 vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE; in fsl_ssi_setup_regvals()
599 vals[RX].scr = vals[TX].scr = 0; in fsl_ssi_setup_regvals()
601 if (ssi->use_dual_fifo) { in fsl_ssi_setup_regvals()
602 vals[RX].srcr |= SSI_SRCR_RFEN1; in fsl_ssi_setup_regvals()
606 if (ssi->use_dma) { in fsl_ssi_setup_regvals()
607 vals[RX].sier |= SSI_SIER_RDMAE; in fsl_ssi_setup_regvals()
610 vals[RX].sier |= SSI_SIER_RIE; in fsl_ssi_setup_regvals()
617 struct regmap *regs = ssi->regs; in fsl_ssi_setup_ac97()
641 ret = clk_prepare_enable(ssi->clk); in fsl_ssi_startup()
651 if (ssi->use_dual_fifo || ssi->use_dyna_fifo) in fsl_ssi_startup()
652 snd_pcm_hw_constraint_step(substream->runtime, 0, in fsl_ssi_startup()
664 clk_disable_unprepare(ssi->clk); in fsl_ssi_shutdown()
668 * fsl_ssi_set_bclk - Configure Digital Audio Interface bit clock
676 * freq: Output BCLK frequency = samplerate * slots * slot_width
677 * (In 2-channel I2S Master mode, slot_width is fixed 32)
683 bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in fsl_ssi_set_bclk()
685 struct regmap *regs = ssi->regs; in fsl_ssi_set_bclk()
690 unsigned int slots = 2; in fsl_ssi_set_bclk() local
696 /* Override slots and slot_width if being specifically set... */ in fsl_ssi_set_bclk()
697 if (ssi->slots) in fsl_ssi_set_bclk()
698 slots = ssi->slots; in fsl_ssi_set_bclk()
699 if (ssi->slot_width) in fsl_ssi_set_bclk()
700 slot_width = ssi->slot_width; in fsl_ssi_set_bclk()
704 (ssi->i2s_net & SSI_SCR_I2S_MODE_MASK) == SSI_SCR_I2S_MODE_MASTER) in fsl_ssi_set_bclk()
708 freq = slots * slot_width * params_rate(hw_params); in fsl_ssi_set_bclk()
710 /* Don't apply it to any non-baudclk circumstance */ in fsl_ssi_set_bclk()
711 if (IS_ERR(ssi->baudclk)) in fsl_ssi_set_bclk()
712 return -EINVAL; in fsl_ssi_set_bclk()
718 if (freq * 5 > clk_get_rate(ssi->clk)) { in fsl_ssi_set_bclk()
719 dev_err(dai->dev, "bitclk > ipgclk / 5\n"); in fsl_ssi_set_bclk()
720 return -EINVAL; in fsl_ssi_set_bclk()
723 baudclk_is_used = ssi->baudclk_streams & ~(BIT(substream->stream)); in fsl_ssi_set_bclk()
735 clkrate = clk_get_rate(ssi->baudclk); in fsl_ssi_set_bclk()
737 clkrate = clk_round_rate(ssi->baudclk, tmprate); in fsl_ssi_set_bclk()
745 sub = freq - afreq; in fsl_ssi_set_bclk()
747 sub = afreq - freq; in fsl_ssi_set_bclk()
768 dev_err(dai->dev, "failed to handle the required sysclk\n"); in fsl_ssi_set_bclk()
769 return -EINVAL; in fsl_ssi_set_bclk()
775 /* STCCR is used for RX in synchronous mode */ in fsl_ssi_set_bclk()
776 tx2 = tx || ssi->synchronous; in fsl_ssi_set_bclk()
780 ret = clk_set_rate(ssi->baudclk, baudrate); in fsl_ssi_set_bclk()
782 dev_err(dai->dev, "failed to set baudclk rate\n"); in fsl_ssi_set_bclk()
783 return -EINVAL; in fsl_ssi_set_bclk()
791 * fsl_ssi_hw_params - Configure SSI based on PCM hardware parameters
799 * running in synchronous mode (both TX and RX use STCCR), it is not
800 * safe to re-configure them when both two streams start running.
808 bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in fsl_ssi_hw_params()
810 struct fsl_ssi_regvals *vals = ssi->regvals; in fsl_ssi_hw_params()
811 struct regmap *regs = ssi->regs; in fsl_ssi_hw_params()
823 if (!(ssi->baudclk_streams & BIT(substream->stream))) { in fsl_ssi_hw_params()
824 ret = clk_prepare_enable(ssi->baudclk); in fsl_ssi_hw_params()
828 ssi->baudclk_streams |= BIT(substream->stream); in fsl_ssi_hw_params()
838 if (ssi->streams && ssi->synchronous) in fsl_ssi_hw_params()
843 * Keep the ssi->i2s_net intact while having a local variable in fsl_ssi_hw_params()
845 * ssi->i2s_net will lose the settings for regular use cases. in fsl_ssi_hw_params()
847 u8 i2s_net = ssi->i2s_net; in fsl_ssi_hw_params()
849 /* Normal + Network mode to send 16-bit data in 32-bit frames */ in fsl_ssi_hw_params()
853 /* Use Normal mode to send mono data at 1st slot of 2 slots */ in fsl_ssi_hw_params()
862 tx2 = tx || ssi->synchronous; in fsl_ssi_hw_params()
865 if (ssi->use_dyna_fifo) { in fsl_ssi_hw_params()
867 ssi->audio_config[0].n_fifos_dst = 1; in fsl_ssi_hw_params()
868 ssi->audio_config[1].n_fifos_src = 1; in fsl_ssi_hw_params()
869 vals[RX].srcr &= ~SSI_SRCR_RFEN1; in fsl_ssi_hw_params()
871 vals[RX].scr &= ~SSI_SCR_TCH_EN; in fsl_ssi_hw_params()
874 ssi->audio_config[0].n_fifos_dst = 2; in fsl_ssi_hw_params()
875 ssi->audio_config[1].n_fifos_src = 2; in fsl_ssi_hw_params()
876 vals[RX].srcr |= SSI_SRCR_RFEN1; in fsl_ssi_hw_params()
878 vals[RX].scr |= SSI_SCR_TCH_EN; in fsl_ssi_hw_params()
881 ssi->dma_params_tx.peripheral_config = &ssi->audio_config[0]; in fsl_ssi_hw_params()
882 ssi->dma_params_tx.peripheral_size = sizeof(ssi->audio_config[0]); in fsl_ssi_hw_params()
883 ssi->dma_params_rx.peripheral_config = &ssi->audio_config[1]; in fsl_ssi_hw_params()
884 ssi->dma_params_rx.peripheral_size = sizeof(ssi->audio_config[1]); in fsl_ssi_hw_params()
897 ssi->baudclk_streams & BIT(substream->stream)) { in fsl_ssi_hw_free()
898 clk_disable_unprepare(ssi->baudclk); in fsl_ssi_hw_free()
899 ssi->baudclk_streams &= ~BIT(substream->stream); in fsl_ssi_hw_free()
908 unsigned int slots; in _fsl_ssi_set_dai_fmt() local
910 ssi->dai_fmt = fmt; in _fsl_ssi_set_dai_fmt()
919 ssi->i2s_net = SSI_SCR_NET; in _fsl_ssi_set_dai_fmt()
924 if (IS_ERR(ssi->baudclk)) { in _fsl_ssi_set_dai_fmt()
925 dev_err(ssi->dev, in _fsl_ssi_set_dai_fmt()
927 return -EINVAL; in _fsl_ssi_set_dai_fmt()
931 ssi->i2s_net |= SSI_SCR_I2S_MODE_MASTER; in _fsl_ssi_set_dai_fmt()
934 ssi->i2s_net |= SSI_SCR_I2S_MODE_SLAVE; in _fsl_ssi_set_dai_fmt()
937 return -EINVAL; in _fsl_ssi_set_dai_fmt()
940 slots = ssi->slots ? : 2; in _fsl_ssi_set_dai_fmt()
941 regmap_update_bits(ssi->regs, REG_SSI_STCCR, in _fsl_ssi_set_dai_fmt()
942 SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots)); in _fsl_ssi_set_dai_fmt()
943 regmap_update_bits(ssi->regs, REG_SSI_SRCCR, in _fsl_ssi_set_dai_fmt()
944 SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots)); in _fsl_ssi_set_dai_fmt()
966 return -EINVAL; in _fsl_ssi_set_dai_fmt()
969 scr |= ssi->i2s_net; in _fsl_ssi_set_dai_fmt()
990 return -EINVAL; in _fsl_ssi_set_dai_fmt()
1008 return -EINVAL; in _fsl_ssi_set_dai_fmt()
1015 if (ssi->synchronous || fsl_ssi_is_ac97(ssi)) { in _fsl_ssi_set_dai_fmt()
1023 regmap_update_bits(ssi->regs, REG_SSI_STCR, mask, stcr); in _fsl_ssi_set_dai_fmt()
1024 regmap_update_bits(ssi->regs, REG_SSI_SRCR, mask, srcr); in _fsl_ssi_set_dai_fmt()
1028 regmap_update_bits(ssi->regs, REG_SSI_SCR, mask, scr); in _fsl_ssi_set_dai_fmt()
1034 * fsl_ssi_set_dai_fmt - Configure Digital Audio Interface (DAI) Format
1050 * fsl_ssi_set_dai_tdm_slot - Set TDM slot number and slot width
1053 * @rx_mask: mask for RX
1054 * @slots: number of slots
1058 u32 rx_mask, int slots, int slot_width) in fsl_ssi_set_dai_tdm_slot() argument
1061 struct regmap *regs = ssi->regs; in fsl_ssi_set_dai_tdm_slot()
1066 dev_err(dai->dev, "invalid slot width: %d\n", slot_width); in fsl_ssi_set_dai_tdm_slot()
1067 return -EINVAL; in fsl_ssi_set_dai_tdm_slot()
1071 if (ssi->i2s_net && slots < 2) { in fsl_ssi_set_dai_tdm_slot()
1072 dev_err(dai->dev, "slot number should be >= 2 in I2S or NET\n"); in fsl_ssi_set_dai_tdm_slot()
1073 return -EINVAL; in fsl_ssi_set_dai_tdm_slot()
1077 SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots)); in fsl_ssi_set_dai_tdm_slot()
1079 SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots)); in fsl_ssi_set_dai_tdm_slot()
1092 ssi->slot_width = slot_width; in fsl_ssi_set_dai_tdm_slot()
1093 ssi->slots = slots; in fsl_ssi_set_dai_tdm_slot()
1099 * fsl_ssi_trigger - Start or stop SSI and corresponding DMA transaction.
1112 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in fsl_ssi_trigger()
1121 * send valid data to slots other than normal playback slots. in fsl_ssi_trigger()
1137 return -EINVAL; in fsl_ssi_trigger()
1147 if (ssi->soc->imx && ssi->use_dma) in fsl_ssi_dai_probe()
1148 snd_soc_dai_init_dma_data(dai, &ssi->dma_params_tx, in fsl_ssi_dai_probe()
1149 &ssi->dma_params_rx); in fsl_ssi_dai_probe()
1167 .stream_name = "CPU-Playback",
1174 .stream_name = "CPU-Capture",
1184 .name = "fsl-ssi",
1202 /* 16-bit capture is broken (errata ERR003778) */
1213 struct regmap *regs = fsl_ac97_data->regs; in fsl_ssi_ac97_write()
1221 mutex_lock(&fsl_ac97_data->ac97_reg_lock); in fsl_ssi_ac97_write()
1223 ret = clk_prepare_enable(fsl_ac97_data->clk); in fsl_ssi_ac97_write()
1240 clk_disable_unprepare(fsl_ac97_data->clk); in fsl_ssi_ac97_write()
1243 mutex_unlock(&fsl_ac97_data->ac97_reg_lock); in fsl_ssi_ac97_write()
1249 struct regmap *regs = fsl_ac97_data->regs; in fsl_ssi_ac97_read()
1255 mutex_lock(&fsl_ac97_data->ac97_reg_lock); in fsl_ssi_ac97_read()
1257 ret = clk_prepare_enable(fsl_ac97_data->clk); in fsl_ssi_ac97_read()
1273 clk_disable_unprepare(fsl_ac97_data->clk); in fsl_ssi_ac97_read()
1276 mutex_unlock(&fsl_ac97_data->ac97_reg_lock); in fsl_ssi_ac97_read()
1286 * fsl_ssi_hw_init - Initialize SSI registers
1291 u32 wm = ssi->fifo_watermark; in fsl_ssi_hw_init()
1297 regmap_write(ssi->regs, REG_SSI_SFCSR, in fsl_ssi_hw_init()
1302 if (ssi->use_dual_fifo) in fsl_ssi_hw_init()
1303 regmap_update_bits(ssi->regs, REG_SSI_SCR, in fsl_ssi_hw_init()
1308 _fsl_ssi_set_dai_fmt(ssi, ssi->dai_fmt); in fsl_ssi_hw_init()
1316 * fsl_ssi_hw_clean - Clear SSI registers
1324 regmap_update_bits(ssi->regs, REG_SSI_SCR, in fsl_ssi_hw_clean()
1327 regmap_write(ssi->regs, REG_SSI_SACNT, 0); in fsl_ssi_hw_clean()
1329 regmap_write(ssi->regs, REG_SSI_SOR, 0); in fsl_ssi_hw_clean()
1330 /* Disable SSI -- software reset */ in fsl_ssi_hw_clean()
1331 regmap_update_bits(ssi->regs, REG_SSI_SCR, SSI_SCR_SSIEN, 0); in fsl_ssi_hw_clean()
1336 * Make every character in a string lower-case
1349 struct device *dev = &pdev->dev; in fsl_ssi_imx_probe()
1353 if (ssi->has_ipg_clk_name) in fsl_ssi_imx_probe()
1354 ssi->clk = devm_clk_get(dev, "ipg"); in fsl_ssi_imx_probe()
1356 ssi->clk = devm_clk_get(dev, NULL); in fsl_ssi_imx_probe()
1357 if (IS_ERR(ssi->clk)) { in fsl_ssi_imx_probe()
1358 ret = PTR_ERR(ssi->clk); in fsl_ssi_imx_probe()
1364 if (!ssi->has_ipg_clk_name) { in fsl_ssi_imx_probe()
1365 ret = clk_prepare_enable(ssi->clk); in fsl_ssi_imx_probe()
1373 ssi->baudclk = devm_clk_get(dev, "baud"); in fsl_ssi_imx_probe()
1374 if (IS_ERR(ssi->baudclk)) in fsl_ssi_imx_probe()
1376 PTR_ERR(ssi->baudclk)); in fsl_ssi_imx_probe()
1378 ssi->dma_params_tx.maxburst = ssi->dma_maxburst; in fsl_ssi_imx_probe()
1379 ssi->dma_params_rx.maxburst = ssi->dma_maxburst; in fsl_ssi_imx_probe()
1380 ssi->dma_params_tx.addr = ssi->ssi_phys + REG_SSI_STX0; in fsl_ssi_imx_probe()
1381 ssi->dma_params_rx.addr = ssi->ssi_phys + REG_SSI_SRX0; in fsl_ssi_imx_probe()
1384 if (ssi->use_dual_fifo || ssi->use_dyna_fifo) { in fsl_ssi_imx_probe()
1385 ssi->dma_params_tx.maxburst &= ~0x1; in fsl_ssi_imx_probe()
1386 ssi->dma_params_rx.maxburst &= ~0x1; in fsl_ssi_imx_probe()
1389 if (!ssi->use_dma) { in fsl_ssi_imx_probe()
1391 * Some boards use an incompatible codec. Use imx-fiq-pcm-audio in fsl_ssi_imx_probe()
1394 ssi->fiq_params.irq = ssi->irq; in fsl_ssi_imx_probe()
1395 ssi->fiq_params.base = iomem; in fsl_ssi_imx_probe()
1396 ssi->fiq_params.dma_params_rx = &ssi->dma_params_rx; in fsl_ssi_imx_probe()
1397 ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx; in fsl_ssi_imx_probe()
1399 ret = imx_pcm_fiq_init(pdev, &ssi->fiq_params); in fsl_ssi_imx_probe()
1413 if (!ssi->has_ipg_clk_name) in fsl_ssi_imx_probe()
1414 clk_disable_unprepare(ssi->clk); in fsl_ssi_imx_probe()
1421 if (!ssi->use_dma) in fsl_ssi_imx_clean()
1423 if (!ssi->has_ipg_clk_name) in fsl_ssi_imx_clean()
1424 clk_disable_unprepare(ssi->clk); in fsl_ssi_imx_clean()
1429 struct device *dev = ssi->dev; in fsl_ssi_probe_from_dt()
1430 struct device_node *np = dev->of_node; in fsl_ssi_probe_from_dt()
1436 ret = of_property_match_string(np, "clock-names", "ipg"); in fsl_ssi_probe_from_dt()
1438 ssi->has_ipg_clk_name = ret >= 0; in fsl_ssi_probe_from_dt()
1442 if (sprop && !strcmp(sprop, "ac97-slave")) { in fsl_ssi_probe_from_dt()
1443 ssi->dai_fmt = FSLSSI_AC97_DAIFMT; in fsl_ssi_probe_from_dt()
1445 ret = of_property_read_u32(np, "cell-index", &ssi->card_idx); in fsl_ssi_probe_from_dt()
1448 return -EINVAL; in fsl_ssi_probe_from_dt()
1450 strcpy(ssi->card_name, "ac97-codec"); in fsl_ssi_probe_from_dt()
1451 } else if (!of_property_read_bool(np, "fsl,ssi-asynchronous")) { in fsl_ssi_probe_from_dt()
1453 * In synchronous mode, STCK and STFS ports are used by RX in fsl_ssi_probe_from_dt()
1461 ssi->synchronous = true; in fsl_ssi_probe_from_dt()
1465 ssi->use_dma = !of_property_read_bool(np, "fsl,fiq-stream-filter"); in fsl_ssi_probe_from_dt()
1468 iprop = of_get_property(np, "fsl,fifo-depth", NULL); in fsl_ssi_probe_from_dt()
1470 ssi->fifo_depth = be32_to_cpup(iprop); in fsl_ssi_probe_from_dt()
1472 ssi->fifo_depth = 8; in fsl_ssi_probe_from_dt()
1476 if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) in fsl_ssi_probe_from_dt()
1477 ssi->use_dual_fifo = true; in fsl_ssi_probe_from_dt()
1479 if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_MULTI_SAI) in fsl_ssi_probe_from_dt()
1480 ssi->use_dyna_fifo = true; in fsl_ssi_probe_from_dt()
1489 if (!ssi->card_name[0] && of_get_property(np, "codec-handle", NULL)) { in fsl_ssi_probe_from_dt()
1498 snprintf(ssi->card_name, sizeof(ssi->card_name), in fsl_ssi_probe_from_dt()
1499 "snd-soc-%s", sprop); in fsl_ssi_probe_from_dt()
1500 make_lowercase(ssi->card_name); in fsl_ssi_probe_from_dt()
1501 ssi->card_idx = 0; in fsl_ssi_probe_from_dt()
1510 struct device *dev = &pdev->dev; in fsl_ssi_probe()
1518 return -ENOMEM; in fsl_ssi_probe()
1520 ssi->dev = dev; in fsl_ssi_probe()
1521 ssi->soc = of_device_get_match_data(&pdev->dev); in fsl_ssi_probe()
1529 memcpy(&ssi->cpu_dai_drv, &fsl_ssi_ac97_dai, in fsl_ssi_probe()
1533 memcpy(&ssi->cpu_dai_drv, &fsl_ssi_dai_template, in fsl_ssi_probe()
1536 ssi->cpu_dai_drv.name = dev_name(dev); in fsl_ssi_probe()
1541 ssi->ssi_phys = res->start; in fsl_ssi_probe()
1543 if (ssi->soc->imx21regs) { in fsl_ssi_probe()
1544 /* No SACC{ST,EN,DIS} regs in imx21-class SSI */ in fsl_ssi_probe()
1550 if (ssi->has_ipg_clk_name) in fsl_ssi_probe()
1551 ssi->regs = devm_regmap_init_mmio_clk(dev, "ipg", iomem, in fsl_ssi_probe()
1554 ssi->regs = devm_regmap_init_mmio(dev, iomem, &regconfig); in fsl_ssi_probe()
1555 if (IS_ERR(ssi->regs)) { in fsl_ssi_probe()
1557 return PTR_ERR(ssi->regs); in fsl_ssi_probe()
1560 ssi->irq = platform_get_irq(pdev, 0); in fsl_ssi_probe()
1561 if (ssi->irq < 0) in fsl_ssi_probe()
1562 return ssi->irq; in fsl_ssi_probe()
1565 if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) { in fsl_ssi_probe()
1566 ssi->cpu_dai_drv.symmetric_rate = 1; in fsl_ssi_probe()
1567 ssi->cpu_dai_drv.symmetric_channels = 1; in fsl_ssi_probe()
1568 ssi->cpu_dai_drv.symmetric_sample_bits = 1; in fsl_ssi_probe()
1572 * Configure TX and RX DMA watermarks -- when to send a DMA request in fsl_ssi_probe()
1577 switch (ssi->fifo_depth) { in fsl_ssi_probe()
1580 * Set to 8 as a balanced configuration -- When TX FIFO has 8 in fsl_ssi_probe()
1581 * empty slots, send a DMA request to fill these 8 slots. The in fsl_ssi_probe()
1582 * remaining 7 slots should be able to allow DMA to finish the in fsl_ssi_probe()
1583 * transaction before TX FIFO underruns; Same applies to RX. in fsl_ssi_probe()
1587 ssi->fifo_watermark = 8; in fsl_ssi_probe()
1588 ssi->dma_maxburst = 8; in fsl_ssi_probe()
1593 ssi->fifo_watermark = ssi->fifo_depth - 2; in fsl_ssi_probe()
1594 ssi->dma_maxburst = ssi->fifo_depth - 2; in fsl_ssi_probe()
1600 if (ssi->soc->imx) { in fsl_ssi_probe()
1607 mutex_init(&ssi->ac97_reg_lock); in fsl_ssi_probe()
1616 &ssi->cpu_dai_drv, 1); in fsl_ssi_probe()
1622 if (ssi->use_dma) { in fsl_ssi_probe()
1623 ret = devm_request_irq(dev, ssi->irq, fsl_ssi_isr, 0, in fsl_ssi_probe()
1626 dev_err(dev, "failed to claim irq %u\n", ssi->irq); in fsl_ssi_probe()
1631 fsl_ssi_debugfs_create(&ssi->dbg_stats, dev); in fsl_ssi_probe()
1637 if (ssi->card_name[0]) { in fsl_ssi_probe()
1648 ssi->card_pdev = platform_device_register_data(parent, in fsl_ssi_probe()
1649 ssi->card_name, ssi->card_idx, NULL, 0); in fsl_ssi_probe()
1650 if (IS_ERR(ssi->card_pdev)) { in fsl_ssi_probe()
1651 ret = PTR_ERR(ssi->card_pdev); in fsl_ssi_probe()
1653 ssi->card_name, ret); in fsl_ssi_probe()
1661 fsl_ssi_debugfs_remove(&ssi->dbg_stats); in fsl_ssi_probe()
1667 mutex_destroy(&ssi->ac97_reg_lock); in fsl_ssi_probe()
1669 if (ssi->soc->imx) in fsl_ssi_probe()
1677 struct fsl_ssi *ssi = dev_get_drvdata(&pdev->dev); in fsl_ssi_remove()
1679 fsl_ssi_debugfs_remove(&ssi->dbg_stats); in fsl_ssi_remove()
1681 if (ssi->card_pdev) in fsl_ssi_remove()
1682 platform_device_unregister(ssi->card_pdev); in fsl_ssi_remove()
1687 if (ssi->soc->imx) in fsl_ssi_remove()
1692 mutex_destroy(&ssi->ac97_reg_lock); in fsl_ssi_remove()
1699 struct regmap *regs = ssi->regs; in fsl_ssi_suspend()
1701 regmap_read(regs, REG_SSI_SFCSR, &ssi->regcache_sfcsr); in fsl_ssi_suspend()
1702 regmap_read(regs, REG_SSI_SACNT, &ssi->regcache_sacnt); in fsl_ssi_suspend()
1713 struct regmap *regs = ssi->regs; in fsl_ssi_resume()
1720 ssi->regcache_sfcsr); in fsl_ssi_resume()
1721 regmap_write(regs, REG_SSI_SACNT, ssi->regcache_sacnt); in fsl_ssi_resume()
1732 .name = "fsl-ssi-dai",
1742 MODULE_ALIAS("platform:fsl-ssi-dai");