Lines Matching +full:i2s +full:- +full:regs
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:
16 // we receive in our (PCM-) data stream. The only chance we have is to
52 #include "imx-pcm.h"
54 /* Define RX and TX to index ssi->regvals array; Can be 0 or 1 only */
65 * (bit-endianness must match byte-endianness). Processors typically write
67 * written in. So if the host CPU is big-endian, then only big-endian
90 * - SSI inputs external bit clock and outputs frame sync clock -- CBM_CFS
91 * - Also have NB_NF to mark these two clocks will not be inverted
200 bool imx21regs; /* imx21-class SSI - no SACC{ST,EN,DIS} regs */
206 * struct fsl_ssi - per-SSI private data
207 * @regs: Pointer to the regmap registers
212 * @i2s_net: I2S and Network mode configurations of SCR register
214 * @synchronous: Use synchronous mode - both of TX and RX use STCK and SFCK
223 * @baudclk: Clock source to generate bit and frame-sync clocks
239 * @dev: Pointer to &pdev->dev
248 struct regmap *regs; member
297 * cannot be changed after SSI starts running -- a software reset
339 { .compatible = "fsl,mpc8610-ssi", .data = &fsl_ssi_mpc8610 },
340 { .compatible = "fsl,imx51-ssi", .data = &fsl_ssi_imx51 },
341 { .compatible = "fsl,imx35-ssi", .data = &fsl_ssi_imx35 },
342 { .compatible = "fsl,imx21-ssi", .data = &fsl_ssi_imx21 },
349 return (ssi->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) == in fsl_ssi_is_ac97()
355 return (ssi->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == in fsl_ssi_is_i2s_master()
361 return (ssi->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == in fsl_ssi_is_i2s_cbm_cfs()
366 * fsl_ssi_irq - Interrupt handler to gather states
373 struct regmap *regs = ssi->regs; in fsl_ssi_isr() local
376 regmap_read(regs, REG_SSI_SISR, &sisr); in fsl_ssi_isr()
378 sisr2 = sisr & ssi->soc->sisr_write_mask; in fsl_ssi_isr()
381 regmap_write(regs, REG_SSI_SISR, sisr2); in fsl_ssi_isr()
383 fsl_ssi_dbg_isr(&ssi->dbg_stats, sisr); in fsl_ssi_isr()
389 * fsl_ssi_config_enable - Set SCR, SIER, STCR and SRCR registers with
401 struct fsl_ssi_regvals *vals = ssi->regvals; in fsl_ssi_config_enable()
406 regmap_update_bits(ssi->regs, REG_SSI_SOR, in fsl_ssi_config_enable()
414 if (ssi->soc->offline_config && ssi->streams) in fsl_ssi_config_enable()
417 if (ssi->soc->offline_config) { in fsl_ssi_config_enable()
433 regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, srcr); in fsl_ssi_config_enable()
434 regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, stcr); in fsl_ssi_config_enable()
435 regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, sier); in fsl_ssi_config_enable()
444 if (ssi->use_dma && tx) { in fsl_ssi_config_enable()
449 regmap_update_bits(ssi->regs, REG_SSI_SCR, in fsl_ssi_config_enable()
452 /* Busy wait until TX FIFO not empty -- DMA working */ in fsl_ssi_config_enable()
454 regmap_read(ssi->regs, REG_SSI_SFCSR, &sfcsr); in fsl_ssi_config_enable()
457 } while (--try); in fsl_ssi_config_enable()
459 /* FIFO still empty -- something might be wrong */ in fsl_ssi_config_enable()
461 dev_warn(ssi->dev, "Timeout waiting TX FIFO filling\n"); in fsl_ssi_config_enable()
464 regmap_update_bits(ssi->regs, REG_SSI_SCR, in fsl_ssi_config_enable()
468 ssi->streams |= BIT(dir); in fsl_ssi_config_enable()
492 * fsl_ssi_config_disable - Unset SCR, SIER, STCR and SRCR registers
511 aactive = ssi->streams & BIT(adir); in fsl_ssi_config_disable()
513 vals = &ssi->regvals[dir]; in fsl_ssi_config_disable()
516 avals = &ssi->regvals[adir]; in fsl_ssi_config_disable()
522 scr = ssi_excl_shared_bits(vals->scr, avals->scr, aactive); in fsl_ssi_config_disable()
525 regmap_update_bits(ssi->regs, REG_SSI_SCR, scr, 0); in fsl_ssi_config_disable()
528 ssi->streams &= ~BIT(dir); in fsl_ssi_config_disable()
534 if (ssi->soc->offline_config && aactive) in fsl_ssi_config_disable()
537 if (ssi->soc->offline_config) { in fsl_ssi_config_disable()
539 srcr = vals->srcr | avals->srcr; in fsl_ssi_config_disable()
540 stcr = vals->stcr | avals->stcr; in fsl_ssi_config_disable()
541 sier = vals->sier | avals->sier; in fsl_ssi_config_disable()
547 sier = ssi_excl_shared_bits(vals->sier, avals->sier, aactive); in fsl_ssi_config_disable()
548 srcr = ssi_excl_shared_bits(vals->srcr, avals->srcr, aactive); in fsl_ssi_config_disable()
549 stcr = ssi_excl_shared_bits(vals->stcr, avals->stcr, aactive); in fsl_ssi_config_disable()
553 regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, 0); in fsl_ssi_config_disable()
554 regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, 0); in fsl_ssi_config_disable()
555 regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, 0); in fsl_ssi_config_disable()
559 regmap_update_bits(ssi->regs, REG_SSI_SOR, in fsl_ssi_config_disable()
565 struct regmap *regs = ssi->regs; in fsl_ssi_tx_ac97_saccst_setup() local
567 /* no SACC{ST,EN,DIS} regs on imx21-class SSI */ in fsl_ssi_tx_ac97_saccst_setup()
568 if (!ssi->soc->imx21regs) { in fsl_ssi_tx_ac97_saccst_setup()
570 regmap_write(regs, REG_SSI_SACCDIS, 0xff); in fsl_ssi_tx_ac97_saccst_setup()
571 /* Enable slots 3 & 4 -- PCM Playback Left & Right channels */ in fsl_ssi_tx_ac97_saccst_setup()
572 regmap_write(regs, REG_SSI_SACCEN, 0x300); in fsl_ssi_tx_ac97_saccst_setup()
577 * fsl_ssi_setup_regvals - Cache critical bits of SIER, SRCR, STCR and
583 struct fsl_ssi_regvals *vals = ssi->regvals; in fsl_ssi_setup_regvals()
596 if (ssi->use_dual_fifo) { in fsl_ssi_setup_regvals()
601 if (ssi->use_dma) { in fsl_ssi_setup_regvals()
612 struct regmap *regs = ssi->regs; in fsl_ssi_setup_ac97() local
615 regmap_write(regs, REG_SSI_STCCR, SSI_SxCCR_WL(17) | SSI_SxCCR_DC(13)); in fsl_ssi_setup_ac97()
616 regmap_write(regs, REG_SSI_SRCCR, SSI_SxCCR_WL(17) | SSI_SxCCR_DC(13)); in fsl_ssi_setup_ac97()
619 regmap_write(regs, REG_SSI_SACNT, SSI_SACNT_AC97EN | SSI_SACNT_FV); in fsl_ssi_setup_ac97()
622 regmap_update_bits(regs, REG_SSI_SCR, in fsl_ssi_setup_ac97()
626 regmap_write(regs, REG_SSI_SOR, SSI_SOR_WAIT(3)); in fsl_ssi_setup_ac97()
636 ret = clk_prepare_enable(ssi->clk); in fsl_ssi_startup()
646 if (ssi->use_dual_fifo) in fsl_ssi_startup()
647 snd_pcm_hw_constraint_step(substream->runtime, 0, in fsl_ssi_startup()
659 clk_disable_unprepare(ssi->clk); in fsl_ssi_shutdown()
663 * fsl_ssi_set_bclk - Configure Digital Audio Interface bit clock
672 * (In 2-channel I2S Master mode, slot_width is fixed 32)
678 bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in fsl_ssi_set_bclk()
680 struct regmap *regs = ssi->regs; in fsl_ssi_set_bclk() local
692 if (ssi->slots) in fsl_ssi_set_bclk()
693 slots = ssi->slots; in fsl_ssi_set_bclk()
694 if (ssi->slot_width) in fsl_ssi_set_bclk()
695 slot_width = ssi->slot_width; in fsl_ssi_set_bclk()
697 /* ...but force 32 bits for stereo audio using I2S Master Mode */ in fsl_ssi_set_bclk()
699 (ssi->i2s_net & SSI_SCR_I2S_MODE_MASK) == SSI_SCR_I2S_MODE_MASTER) in fsl_ssi_set_bclk()
705 /* Don't apply it to any non-baudclk circumstance */ in fsl_ssi_set_bclk()
706 if (IS_ERR(ssi->baudclk)) in fsl_ssi_set_bclk()
707 return -EINVAL; in fsl_ssi_set_bclk()
713 if (freq * 5 > clk_get_rate(ssi->clk)) { in fsl_ssi_set_bclk()
714 dev_err(dai->dev, "bitclk > ipgclk / 5\n"); in fsl_ssi_set_bclk()
715 return -EINVAL; in fsl_ssi_set_bclk()
718 baudclk_is_used = ssi->baudclk_streams & ~(BIT(substream->stream)); in fsl_ssi_set_bclk()
730 clkrate = clk_get_rate(ssi->baudclk); in fsl_ssi_set_bclk()
732 clkrate = clk_round_rate(ssi->baudclk, tmprate); in fsl_ssi_set_bclk()
740 sub = freq - afreq; in fsl_ssi_set_bclk()
742 sub = afreq - freq; in fsl_ssi_set_bclk()
763 dev_err(dai->dev, "failed to handle the required sysclk\n"); in fsl_ssi_set_bclk()
764 return -EINVAL; in fsl_ssi_set_bclk()
772 tx2 = tx || ssi->synchronous; in fsl_ssi_set_bclk()
773 regmap_update_bits(regs, REG_SSI_SxCCR(tx2), mask, stccr); in fsl_ssi_set_bclk()
776 ret = clk_set_rate(ssi->baudclk, baudrate); in fsl_ssi_set_bclk()
778 dev_err(dai->dev, "failed to set baudclk rate\n"); in fsl_ssi_set_bclk()
779 return -EINVAL; in fsl_ssi_set_bclk()
787 * fsl_ssi_hw_params - Configure SSI based on PCM hardware parameters
796 * safe to re-configure them when both two streams start running.
804 bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in fsl_ssi_hw_params()
806 struct regmap *regs = ssi->regs; in fsl_ssi_hw_params() local
818 if (!(ssi->baudclk_streams & BIT(substream->stream))) { in fsl_ssi_hw_params()
819 ret = clk_prepare_enable(ssi->baudclk); in fsl_ssi_hw_params()
823 ssi->baudclk_streams |= BIT(substream->stream); in fsl_ssi_hw_params()
833 if (ssi->streams && ssi->synchronous) in fsl_ssi_hw_params()
838 * Keep the ssi->i2s_net intact while having a local variable in fsl_ssi_hw_params()
840 * ssi->i2s_net will lose the settings for regular use cases. in fsl_ssi_hw_params()
842 u8 i2s_net = ssi->i2s_net; in fsl_ssi_hw_params()
844 /* Normal + Network mode to send 16-bit data in 32-bit frames */ in fsl_ssi_hw_params()
852 regmap_update_bits(regs, REG_SSI_SCR, in fsl_ssi_hw_params()
857 tx2 = tx || ssi->synchronous; in fsl_ssi_hw_params()
858 regmap_update_bits(regs, REG_SSI_SxCCR(tx2), SSI_SxCCR_WL_MASK, wl); in fsl_ssi_hw_params()
870 ssi->baudclk_streams & BIT(substream->stream)) { in fsl_ssi_hw_free()
871 clk_disable_unprepare(ssi->baudclk); in fsl_ssi_hw_free()
872 ssi->baudclk_streams &= ~BIT(substream->stream); in fsl_ssi_hw_free()
883 ssi->dai_fmt = fmt; in _fsl_ssi_set_dai_fmt()
892 ssi->i2s_net = SSI_SCR_NET; in _fsl_ssi_set_dai_fmt()
897 if (IS_ERR(ssi->baudclk)) { in _fsl_ssi_set_dai_fmt()
898 dev_err(ssi->dev, in _fsl_ssi_set_dai_fmt()
900 return -EINVAL; in _fsl_ssi_set_dai_fmt()
904 ssi->i2s_net |= SSI_SCR_I2S_MODE_MASTER; in _fsl_ssi_set_dai_fmt()
907 ssi->i2s_net |= SSI_SCR_I2S_MODE_SLAVE; in _fsl_ssi_set_dai_fmt()
910 return -EINVAL; in _fsl_ssi_set_dai_fmt()
913 slots = ssi->slots ? : 2; in _fsl_ssi_set_dai_fmt()
914 regmap_update_bits(ssi->regs, REG_SSI_STCCR, in _fsl_ssi_set_dai_fmt()
916 regmap_update_bits(ssi->regs, REG_SSI_SRCCR, in _fsl_ssi_set_dai_fmt()
939 return -EINVAL; in _fsl_ssi_set_dai_fmt()
942 scr |= ssi->i2s_net; in _fsl_ssi_set_dai_fmt()
963 return -EINVAL; in _fsl_ssi_set_dai_fmt()
981 return -EINVAL; in _fsl_ssi_set_dai_fmt()
988 if (ssi->synchronous || fsl_ssi_is_ac97(ssi)) { in _fsl_ssi_set_dai_fmt()
996 regmap_update_bits(ssi->regs, REG_SSI_STCR, mask, stcr); in _fsl_ssi_set_dai_fmt()
997 regmap_update_bits(ssi->regs, REG_SSI_SRCR, mask, srcr); in _fsl_ssi_set_dai_fmt()
1001 regmap_update_bits(ssi->regs, REG_SSI_SCR, mask, scr); in _fsl_ssi_set_dai_fmt()
1007 * fsl_ssi_set_dai_fmt - Configure Digital Audio Interface (DAI) Format
1023 * fsl_ssi_set_dai_tdm_slot - Set TDM slot number and slot width
1034 struct regmap *regs = ssi->regs; in fsl_ssi_set_dai_tdm_slot() local
1039 dev_err(dai->dev, "invalid slot width: %d\n", slot_width); in fsl_ssi_set_dai_tdm_slot()
1040 return -EINVAL; in fsl_ssi_set_dai_tdm_slot()
1043 /* The slot number should be >= 2 if using Network mode or I2S mode */ in fsl_ssi_set_dai_tdm_slot()
1044 if (ssi->i2s_net && slots < 2) { in fsl_ssi_set_dai_tdm_slot()
1045 dev_err(dai->dev, "slot number should be >= 2 in I2S or NET\n"); in fsl_ssi_set_dai_tdm_slot()
1046 return -EINVAL; in fsl_ssi_set_dai_tdm_slot()
1049 regmap_update_bits(regs, REG_SSI_STCCR, in fsl_ssi_set_dai_tdm_slot()
1051 regmap_update_bits(regs, REG_SSI_SRCCR, in fsl_ssi_set_dai_tdm_slot()
1055 regmap_read(regs, REG_SSI_SCR, &val); in fsl_ssi_set_dai_tdm_slot()
1057 regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, SSI_SCR_SSIEN); in fsl_ssi_set_dai_tdm_slot()
1059 regmap_write(regs, REG_SSI_STMSK, ~tx_mask); in fsl_ssi_set_dai_tdm_slot()
1060 regmap_write(regs, REG_SSI_SRMSK, ~rx_mask); in fsl_ssi_set_dai_tdm_slot()
1063 regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, val); in fsl_ssi_set_dai_tdm_slot()
1065 ssi->slot_width = slot_width; in fsl_ssi_set_dai_tdm_slot()
1066 ssi->slots = slots; in fsl_ssi_set_dai_tdm_slot()
1072 * fsl_ssi_trigger - Start or stop SSI and corresponding DMA transaction.
1085 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; in fsl_ssi_trigger()
1110 return -EINVAL; in fsl_ssi_trigger()
1120 if (ssi->soc->imx && ssi->use_dma) in fsl_ssi_dai_probe()
1121 snd_soc_dai_init_dma_data(dai, &ssi->dma_params_tx, in fsl_ssi_dai_probe()
1122 &ssi->dma_params_rx); in fsl_ssi_dai_probe()
1140 .stream_name = "CPU-Playback",
1147 .stream_name = "CPU-Capture",
1157 .name = "fsl-ssi",
1175 /* 16-bit capture is broken (errata ERR003778) */
1186 struct regmap *regs = fsl_ac97_data->regs; in fsl_ssi_ac97_write() local
1194 mutex_lock(&fsl_ac97_data->ac97_reg_lock); in fsl_ssi_ac97_write()
1196 ret = clk_prepare_enable(fsl_ac97_data->clk); in fsl_ssi_ac97_write()
1204 regmap_write(regs, REG_SSI_SACADD, lreg); in fsl_ssi_ac97_write()
1207 regmap_write(regs, REG_SSI_SACDAT, lval); in fsl_ssi_ac97_write()
1209 regmap_update_bits(regs, REG_SSI_SACNT, in fsl_ssi_ac97_write()
1213 clk_disable_unprepare(fsl_ac97_data->clk); in fsl_ssi_ac97_write()
1216 mutex_unlock(&fsl_ac97_data->ac97_reg_lock); in fsl_ssi_ac97_write()
1222 struct regmap *regs = fsl_ac97_data->regs; in fsl_ssi_ac97_read() local
1228 mutex_lock(&fsl_ac97_data->ac97_reg_lock); in fsl_ssi_ac97_read()
1230 ret = clk_prepare_enable(fsl_ac97_data->clk); in fsl_ssi_ac97_read()
1237 regmap_write(regs, REG_SSI_SACADD, lreg); in fsl_ssi_ac97_read()
1238 regmap_update_bits(regs, REG_SSI_SACNT, in fsl_ssi_ac97_read()
1243 regmap_read(regs, REG_SSI_SACDAT, ®_val); in fsl_ssi_ac97_read()
1246 clk_disable_unprepare(fsl_ac97_data->clk); in fsl_ssi_ac97_read()
1249 mutex_unlock(&fsl_ac97_data->ac97_reg_lock); in fsl_ssi_ac97_read()
1259 * fsl_ssi_hw_init - Initialize SSI registers
1264 u32 wm = ssi->fifo_watermark; in fsl_ssi_hw_init()
1270 regmap_write(ssi->regs, REG_SSI_SFCSR, in fsl_ssi_hw_init()
1275 if (ssi->use_dual_fifo) in fsl_ssi_hw_init()
1276 regmap_update_bits(ssi->regs, REG_SSI_SCR, in fsl_ssi_hw_init()
1281 _fsl_ssi_set_dai_fmt(ssi, ssi->dai_fmt); in fsl_ssi_hw_init()
1289 * fsl_ssi_hw_clean - Clear SSI registers
1297 regmap_update_bits(ssi->regs, REG_SSI_SCR, in fsl_ssi_hw_clean()
1300 regmap_write(ssi->regs, REG_SSI_SACNT, 0); in fsl_ssi_hw_clean()
1302 regmap_write(ssi->regs, REG_SSI_SOR, 0); in fsl_ssi_hw_clean()
1303 /* Disable SSI -- software reset */ in fsl_ssi_hw_clean()
1304 regmap_update_bits(ssi->regs, REG_SSI_SCR, SSI_SCR_SSIEN, 0); in fsl_ssi_hw_clean()
1309 * Make every character in a string lower-case
1322 struct device *dev = &pdev->dev; in fsl_ssi_imx_probe()
1326 if (ssi->has_ipg_clk_name) in fsl_ssi_imx_probe()
1327 ssi->clk = devm_clk_get(dev, "ipg"); in fsl_ssi_imx_probe()
1329 ssi->clk = devm_clk_get(dev, NULL); in fsl_ssi_imx_probe()
1330 if (IS_ERR(ssi->clk)) { in fsl_ssi_imx_probe()
1331 ret = PTR_ERR(ssi->clk); in fsl_ssi_imx_probe()
1337 if (!ssi->has_ipg_clk_name) { in fsl_ssi_imx_probe()
1338 ret = clk_prepare_enable(ssi->clk); in fsl_ssi_imx_probe()
1346 ssi->baudclk = devm_clk_get(dev, "baud"); in fsl_ssi_imx_probe()
1347 if (IS_ERR(ssi->baudclk)) in fsl_ssi_imx_probe()
1349 PTR_ERR(ssi->baudclk)); in fsl_ssi_imx_probe()
1351 ssi->dma_params_tx.maxburst = ssi->dma_maxburst; in fsl_ssi_imx_probe()
1352 ssi->dma_params_rx.maxburst = ssi->dma_maxburst; in fsl_ssi_imx_probe()
1353 ssi->dma_params_tx.addr = ssi->ssi_phys + REG_SSI_STX0; in fsl_ssi_imx_probe()
1354 ssi->dma_params_rx.addr = ssi->ssi_phys + REG_SSI_SRX0; in fsl_ssi_imx_probe()
1357 if (ssi->use_dual_fifo) { in fsl_ssi_imx_probe()
1358 ssi->dma_params_tx.maxburst &= ~0x1; in fsl_ssi_imx_probe()
1359 ssi->dma_params_rx.maxburst &= ~0x1; in fsl_ssi_imx_probe()
1362 if (!ssi->use_dma) { in fsl_ssi_imx_probe()
1364 * Some boards use an incompatible codec. Use imx-fiq-pcm-audio in fsl_ssi_imx_probe()
1367 ssi->fiq_params.irq = ssi->irq; in fsl_ssi_imx_probe()
1368 ssi->fiq_params.base = iomem; in fsl_ssi_imx_probe()
1369 ssi->fiq_params.dma_params_rx = &ssi->dma_params_rx; in fsl_ssi_imx_probe()
1370 ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx; in fsl_ssi_imx_probe()
1372 ret = imx_pcm_fiq_init(pdev, &ssi->fiq_params); in fsl_ssi_imx_probe()
1384 if (!ssi->has_ipg_clk_name) in fsl_ssi_imx_probe()
1385 clk_disable_unprepare(ssi->clk); in fsl_ssi_imx_probe()
1392 if (!ssi->use_dma) in fsl_ssi_imx_clean()
1394 if (!ssi->has_ipg_clk_name) in fsl_ssi_imx_clean()
1395 clk_disable_unprepare(ssi->clk); in fsl_ssi_imx_clean()
1400 struct device *dev = ssi->dev; in fsl_ssi_probe_from_dt()
1401 struct device_node *np = dev->of_node; in fsl_ssi_probe_from_dt()
1409 if (!of_id || !of_id->data) in fsl_ssi_probe_from_dt()
1410 return -EINVAL; in fsl_ssi_probe_from_dt()
1412 ssi->soc = of_id->data; in fsl_ssi_probe_from_dt()
1414 ret = of_property_match_string(np, "clock-names", "ipg"); in fsl_ssi_probe_from_dt()
1416 ssi->has_ipg_clk_name = ret >= 0; in fsl_ssi_probe_from_dt()
1420 if (sprop && !strcmp(sprop, "ac97-slave")) { in fsl_ssi_probe_from_dt()
1421 ssi->dai_fmt = FSLSSI_AC97_DAIFMT; in fsl_ssi_probe_from_dt()
1423 ret = of_property_read_u32(np, "cell-index", &ssi->card_idx); in fsl_ssi_probe_from_dt()
1426 return -EINVAL; in fsl_ssi_probe_from_dt()
1428 strcpy(ssi->card_name, "ac97-codec"); in fsl_ssi_probe_from_dt()
1429 } else if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) { in fsl_ssi_probe_from_dt()
1439 ssi->synchronous = true; in fsl_ssi_probe_from_dt()
1443 ssi->use_dma = !of_property_read_bool(np, "fsl,fiq-stream-filter"); in fsl_ssi_probe_from_dt()
1446 iprop = of_get_property(np, "fsl,fifo-depth", NULL); in fsl_ssi_probe_from_dt()
1448 ssi->fifo_depth = be32_to_cpup(iprop); in fsl_ssi_probe_from_dt()
1450 ssi->fifo_depth = 8; in fsl_ssi_probe_from_dt()
1454 if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) in fsl_ssi_probe_from_dt()
1455 ssi->use_dual_fifo = true; in fsl_ssi_probe_from_dt()
1465 if (!ssi->card_name[0] && of_get_property(np, "codec-handle", NULL)) { in fsl_ssi_probe_from_dt()
1474 snprintf(ssi->card_name, sizeof(ssi->card_name), in fsl_ssi_probe_from_dt()
1475 "snd-soc-%s", sprop); in fsl_ssi_probe_from_dt()
1476 make_lowercase(ssi->card_name); in fsl_ssi_probe_from_dt()
1477 ssi->card_idx = 0; in fsl_ssi_probe_from_dt()
1486 struct device *dev = &pdev->dev; in fsl_ssi_probe()
1494 return -ENOMEM; in fsl_ssi_probe()
1496 ssi->dev = dev; in fsl_ssi_probe()
1504 memcpy(&ssi->cpu_dai_drv, &fsl_ssi_ac97_dai, in fsl_ssi_probe()
1508 memcpy(&ssi->cpu_dai_drv, &fsl_ssi_dai_template, in fsl_ssi_probe()
1511 ssi->cpu_dai_drv.name = dev_name(dev); in fsl_ssi_probe()
1517 ssi->ssi_phys = res->start; in fsl_ssi_probe()
1519 if (ssi->soc->imx21regs) { in fsl_ssi_probe()
1520 /* No SACC{ST,EN,DIS} regs in imx21-class SSI */ in fsl_ssi_probe()
1526 if (ssi->has_ipg_clk_name) in fsl_ssi_probe()
1527 ssi->regs = devm_regmap_init_mmio_clk(dev, "ipg", iomem, in fsl_ssi_probe()
1530 ssi->regs = devm_regmap_init_mmio(dev, iomem, ®config); in fsl_ssi_probe()
1531 if (IS_ERR(ssi->regs)) { in fsl_ssi_probe()
1533 return PTR_ERR(ssi->regs); in fsl_ssi_probe()
1536 ssi->irq = platform_get_irq(pdev, 0); in fsl_ssi_probe()
1537 if (ssi->irq < 0) in fsl_ssi_probe()
1538 return ssi->irq; in fsl_ssi_probe()
1541 if (ssi->synchronous && !fsl_ssi_is_ac97(ssi)) { in fsl_ssi_probe()
1542 ssi->cpu_dai_drv.symmetric_rates = 1; in fsl_ssi_probe()
1543 ssi->cpu_dai_drv.symmetric_channels = 1; in fsl_ssi_probe()
1544 ssi->cpu_dai_drv.symmetric_samplebits = 1; in fsl_ssi_probe()
1548 * Configure TX and RX DMA watermarks -- when to send a DMA request in fsl_ssi_probe()
1553 switch (ssi->fifo_depth) { in fsl_ssi_probe()
1556 * Set to 8 as a balanced configuration -- When TX FIFO has 8 in fsl_ssi_probe()
1563 ssi->fifo_watermark = 8; in fsl_ssi_probe()
1564 ssi->dma_maxburst = 8; in fsl_ssi_probe()
1569 ssi->fifo_watermark = ssi->fifo_depth - 2; in fsl_ssi_probe()
1570 ssi->dma_maxburst = ssi->fifo_depth - 2; in fsl_ssi_probe()
1576 if (ssi->soc->imx) { in fsl_ssi_probe()
1583 mutex_init(&ssi->ac97_reg_lock); in fsl_ssi_probe()
1592 &ssi->cpu_dai_drv, 1); in fsl_ssi_probe()
1598 if (ssi->use_dma) { in fsl_ssi_probe()
1599 ret = devm_request_irq(dev, ssi->irq, fsl_ssi_isr, 0, in fsl_ssi_probe()
1602 dev_err(dev, "failed to claim irq %u\n", ssi->irq); in fsl_ssi_probe()
1607 fsl_ssi_debugfs_create(&ssi->dbg_stats, dev); in fsl_ssi_probe()
1613 if (ssi->card_name[0]) { in fsl_ssi_probe()
1624 ssi->card_pdev = platform_device_register_data(parent, in fsl_ssi_probe()
1625 ssi->card_name, ssi->card_idx, NULL, 0); in fsl_ssi_probe()
1626 if (IS_ERR(ssi->card_pdev)) { in fsl_ssi_probe()
1627 ret = PTR_ERR(ssi->card_pdev); in fsl_ssi_probe()
1629 ssi->card_name, ret); in fsl_ssi_probe()
1637 fsl_ssi_debugfs_remove(&ssi->dbg_stats); in fsl_ssi_probe()
1643 mutex_destroy(&ssi->ac97_reg_lock); in fsl_ssi_probe()
1645 if (ssi->soc->imx) in fsl_ssi_probe()
1653 struct fsl_ssi *ssi = dev_get_drvdata(&pdev->dev); in fsl_ssi_remove()
1655 fsl_ssi_debugfs_remove(&ssi->dbg_stats); in fsl_ssi_remove()
1657 if (ssi->card_pdev) in fsl_ssi_remove()
1658 platform_device_unregister(ssi->card_pdev); in fsl_ssi_remove()
1663 if (ssi->soc->imx) in fsl_ssi_remove()
1668 mutex_destroy(&ssi->ac97_reg_lock); in fsl_ssi_remove()
1678 struct regmap *regs = ssi->regs; in fsl_ssi_suspend() local
1680 regmap_read(regs, REG_SSI_SFCSR, &ssi->regcache_sfcsr); in fsl_ssi_suspend()
1681 regmap_read(regs, REG_SSI_SACNT, &ssi->regcache_sacnt); in fsl_ssi_suspend()
1683 regcache_cache_only(regs, true); in fsl_ssi_suspend()
1684 regcache_mark_dirty(regs); in fsl_ssi_suspend()
1692 struct regmap *regs = ssi->regs; in fsl_ssi_resume() local
1694 regcache_cache_only(regs, false); in fsl_ssi_resume()
1696 regmap_update_bits(regs, REG_SSI_SFCSR, in fsl_ssi_resume()
1699 ssi->regcache_sfcsr); in fsl_ssi_resume()
1700 regmap_write(regs, REG_SSI_SACNT, ssi->regcache_sacnt); in fsl_ssi_resume()
1702 return regcache_sync(regs); in fsl_ssi_resume()
1712 .name = "fsl-ssi-dai",
1722 MODULE_ALIAS("platform:fsl-ssi-dai");