Lines Matching full:ssc

3  * atmel_ssc_dai.c  --  ALSA SoC ATMEL SSC Audio Layer Platform driver
11 * Based on at91-ssc.c by
25 #include <linux/atmel-ssc.h>
39 * SSC PDC registers required by the PCM DMA engine.
56 * SSC & PDC status bits for transmit and receive.
136 * SSC interrupt handler. Passes PDC interrupts to the DMA
147 ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR) in atmel_ssc_interrupt()
148 & (unsigned long)ssc_readl(ssc_p->ssc->regs, IMR); in atmel_ssc_interrupt()
151 * Loop through the substreams attached to this SSC. If in atmel_ssc_interrupt()
176 * Serial Clock Ratio Considerations section from the SSC documentation:
180 * This allows the SSC to support many slave-mode data transfers.
189 * SSC divider restrictions.
195 struct ssc_device *ssc = ssc_p->ssc; in atmel_ssc_hw_rule_rate() local
215 && ssc->clk_from_rk_pin) in atmel_ssc_hw_rule_rate()
225 && !ssc->clk_from_rk_pin) in atmel_ssc_hw_rule_rate()
279 ssc_readl(ssc_p->ssc->regs, SR)); in atmel_ssc_startup()
281 /* Enable PMC peripheral clock for this SSC */ in atmel_ssc_startup()
283 clk_enable(ssc_p->ssc->clk); in atmel_ssc_startup()
284 ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk); in atmel_ssc_startup()
286 /* Reset the SSC unless initialized to keep it in a clean state */ in atmel_ssc_startup()
288 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); in atmel_ssc_startup()
310 dma_params->ssc = ssc_p->ssc; in atmel_ssc_startup()
326 * Shutdown. Clear DMA parameters and shutdown the SSC if there
345 dma_params->ssc = NULL; in atmel_ssc_shutdown()
355 free_irq(ssc_p->ssc->irq, ssc_p); in atmel_ssc_shutdown()
359 /* Reset the SSC */ in atmel_ssc_shutdown()
360 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); in atmel_ssc_shutdown()
361 /* Clear the SSC dividers */ in atmel_ssc_shutdown()
366 /* Shutdown the SSC clock. */ in atmel_ssc_shutdown()
368 clk_disable(ssc_p->ssc->clk); in atmel_ssc_shutdown()
386 * Record SSC clock dividers for use in hw_params().
452 * Configure the SSC.
461 struct ssc_device *ssc = ssc_p->ssc; in atmel_ssc_hw_params() local
551 * Compute SSC register settings. in atmel_ssc_hw_params()
611 * SSC provides BCLK in atmel_ssc_hw_params()
613 * The SSC transmit and receive clocks are generated from the in atmel_ssc_hw_params()
615 * on the SSC TK line. in atmel_ssc_hw_params()
623 rcmr |= SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? in atmel_ssc_hw_params()
627 tcmr |= SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? in atmel_ssc_hw_params()
657 if (fslen_ext && !ssc->pdata->has_fslen_ext) { in atmel_ssc_hw_params()
658 dev_err(dai->dev, "sample size %d is too large for SSC device\n", in atmel_ssc_hw_params()
668 if (!ssc_p->ssc->pdata->use_dma) { in atmel_ssc_hw_params()
669 ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0); in atmel_ssc_hw_params()
670 ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0); in atmel_ssc_hw_params()
671 ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0); in atmel_ssc_hw_params()
672 ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0); in atmel_ssc_hw_params()
674 ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0); in atmel_ssc_hw_params()
675 ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0); in atmel_ssc_hw_params()
676 ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0); in atmel_ssc_hw_params()
677 ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0); in atmel_ssc_hw_params()
680 ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0, in atmel_ssc_hw_params()
686 clk_disable(ssc_p->ssc->clk); in atmel_ssc_hw_params()
693 /* set SSC clock mode register */ in atmel_ssc_hw_params()
694 ssc_writel(ssc_p->ssc->regs, CMR, cmr_div); in atmel_ssc_hw_params()
697 ssc_writel(ssc_p->ssc->regs, RCMR, rcmr); in atmel_ssc_hw_params()
698 ssc_writel(ssc_p->ssc->regs, RFMR, rfmr); in atmel_ssc_hw_params()
701 ssc_writel(ssc_p->ssc->regs, TCMR, tcmr); in atmel_ssc_hw_params()
702 ssc_writel(ssc_p->ssc->regs, TFMR, tfmr); in atmel_ssc_hw_params()
704 pr_debug("atmel_ssc_dai,hw_params: SSC initialized\n"); in atmel_ssc_hw_params()
724 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable); in atmel_ssc_prepare()
725 ssc_writel(ssc_p->ssc->regs, IDR, dma_params->mask->ssc_error); in atmel_ssc_prepare()
729 ssc_readl(ssc_p->ssc->regs, SR)); in atmel_ssc_prepare()
752 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable); in atmel_ssc_trigger()
755 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable); in atmel_ssc_trigger()
774 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR); in atmel_ssc_suspend()
775 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS)); in atmel_ssc_suspend()
778 ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR); in atmel_ssc_suspend()
779 ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr); in atmel_ssc_suspend()
781 ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR); in atmel_ssc_suspend()
782 ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR); in atmel_ssc_suspend()
783 ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR); in atmel_ssc_suspend()
784 ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR); in atmel_ssc_suspend()
785 ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR); in atmel_ssc_suspend()
801 /* restore SSC register settings */ in atmel_ssc_resume()
802 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr); in atmel_ssc_resume()
803 ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr); in atmel_ssc_resume()
804 ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr); in atmel_ssc_resume()
805 ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr); in atmel_ssc_resume()
806 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr); in atmel_ssc_resume()
809 ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr); in atmel_ssc_resume()
817 ssc_writel(ssc_p->ssc->regs, CR, cr); in atmel_ssc_resume()
858 .name = "atmel-ssc",
865 struct ssc_device *ssc = dev_get_drvdata(dev); in asoc_ssc_init() local
875 if (ssc->pdata->use_dma) in asoc_ssc_init()
889 * atmel_ssc_set_audio - Allocate the specified SSC for audio use.
894 struct ssc_device *ssc; in atmel_ssc_set_audio() local
897 /* If we can grab the SSC briefly to parent the DAI device off it */ in atmel_ssc_set_audio()
898 ssc = ssc_request(ssc_id); in atmel_ssc_set_audio()
899 if (IS_ERR(ssc)) { in atmel_ssc_set_audio()
900 pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n", in atmel_ssc_set_audio()
901 PTR_ERR(ssc)); in atmel_ssc_set_audio()
902 return PTR_ERR(ssc); in atmel_ssc_set_audio()
904 ssc_info[ssc_id].ssc = ssc; in atmel_ssc_set_audio()
907 ret = asoc_ssc_init(&ssc->pdev->dev); in atmel_ssc_set_audio()
915 struct ssc_device *ssc = ssc_info[ssc_id].ssc; in atmel_ssc_put_audio() local
917 ssc_free(ssc); in atmel_ssc_put_audio()
923 MODULE_DESCRIPTION("ATMEL SSC ASoC Interface");