Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * pxa2xx-i2s.c  --  ALSA Soc Audio Layer
0004  *
0005  * Copyright 2005 Wolfson Microelectronics PLC.
0006  * Author: Liam Girdwood
0007  *         lrg@slimlogic.co.uk
0008  */
0009 
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012 #include <linux/device.h>
0013 #include <linux/delay.h>
0014 #include <linux/clk.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/io.h>
0017 #include <sound/core.h>
0018 #include <sound/pcm.h>
0019 #include <sound/initval.h>
0020 #include <sound/soc.h>
0021 #include <sound/pxa2xx-lib.h>
0022 #include <sound/dmaengine_pcm.h>
0023 
0024 #include <linux/platform_data/asoc-pxa.h>
0025 
0026 #include "pxa2xx-i2s.h"
0027 
0028 /*
0029  * I2S Controller Register and Bit Definitions
0030  */
0031 #define SACR0       (0x0000)    /* Global Control Register */
0032 #define SACR1       (0x0004)    /* Serial Audio I 2 S/MSB-Justified Control Register */
0033 #define SASR0       (0x000C)    /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
0034 #define SAIMR       (0x0014)    /* Serial Audio Interrupt Mask Register */
0035 #define SAICR       (0x0018)    /* Serial Audio Interrupt Clear Register */
0036 #define SADIV       (0x0060)    /* Audio Clock Divider Register. */
0037 #define SADR        (0x0080)    /* Serial Audio Data Register (TX and RX FIFO access Register). */
0038 
0039 #define SACR0_RFTH(x)   ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */
0040 #define SACR0_TFTH(x)   ((x) << 8)  /* Tx FIFO Interrupt or DMA Trigger Threshold */
0041 #define SACR0_STRF  (1 << 5)    /* FIFO Select for EFWR Special Function */
0042 #define SACR0_EFWR  (1 << 4)    /* Enable EFWR Function  */
0043 #define SACR0_RST   (1 << 3)    /* FIFO, i2s Register Reset */
0044 #define SACR0_BCKD  (1 << 2)    /* Bit Clock Direction */
0045 #define SACR0_ENB   (1 << 0)    /* Enable I2S Link */
0046 #define SACR1_ENLBF (1 << 5)    /* Enable Loopback */
0047 #define SACR1_DRPL  (1 << 4)    /* Disable Replaying Function */
0048 #define SACR1_DREC  (1 << 3)    /* Disable Recording Function */
0049 #define SACR1_AMSL  (1 << 0)    /* Specify Alternate Mode */
0050 
0051 #define SASR0_I2SOFF    (1 << 7)    /* Controller Status */
0052 #define SASR0_ROR   (1 << 6)    /* Rx FIFO Overrun */
0053 #define SASR0_TUR   (1 << 5)    /* Tx FIFO Underrun */
0054 #define SASR0_RFS   (1 << 4)    /* Rx FIFO Service Request */
0055 #define SASR0_TFS   (1 << 3)    /* Tx FIFO Service Request */
0056 #define SASR0_BSY   (1 << 2)    /* I2S Busy */
0057 #define SASR0_RNE   (1 << 1)    /* Rx FIFO Not Empty */
0058 #define SASR0_TNF   (1 << 0)    /* Tx FIFO Not Empty */
0059 
0060 #define SAICR_ROR   (1 << 6)    /* Clear Rx FIFO Overrun Interrupt */
0061 #define SAICR_TUR   (1 << 5)    /* Clear Tx FIFO Underrun Interrupt */
0062 
0063 #define SAIMR_ROR   (1 << 6)    /* Enable Rx FIFO Overrun Condition Interrupt */
0064 #define SAIMR_TUR   (1 << 5)    /* Enable Tx FIFO Underrun Condition Interrupt */
0065 #define SAIMR_RFS   (1 << 4)    /* Enable Rx FIFO Service Interrupt */
0066 #define SAIMR_TFS   (1 << 3)    /* Enable Tx FIFO Service Interrupt */
0067 
0068 struct pxa_i2s_port {
0069     u32 sadiv;
0070     u32 sacr0;
0071     u32 sacr1;
0072     u32 saimr;
0073     int master;
0074     u32 fmt;
0075 };
0076 static struct pxa_i2s_port pxa_i2s;
0077 static struct clk *clk_i2s;
0078 static int clk_ena = 0;
0079 static void __iomem *i2s_reg_base;
0080 
0081 static struct snd_dmaengine_dai_dma_data pxa2xx_i2s_pcm_stereo_out = {
0082     .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
0083     .chan_name  = "tx",
0084     .maxburst   = 32,
0085 };
0086 
0087 static struct snd_dmaengine_dai_dma_data pxa2xx_i2s_pcm_stereo_in = {
0088     .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
0089     .chan_name  = "rx",
0090     .maxburst   = 32,
0091 };
0092 
0093 static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
0094                   struct snd_soc_dai *dai)
0095 {
0096     struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0097     struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
0098 
0099     if (IS_ERR(clk_i2s))
0100         return PTR_ERR(clk_i2s);
0101 
0102     if (!snd_soc_dai_active(cpu_dai))
0103         writel(0, i2s_reg_base + SACR0);
0104 
0105     return 0;
0106 }
0107 
0108 /* wait for I2S controller to be ready */
0109 static int pxa_i2s_wait(void)
0110 {
0111     int i;
0112 
0113     /* flush the Rx FIFO */
0114     for (i = 0; i < 16; i++)
0115         readl(i2s_reg_base + SADR);
0116     return 0;
0117 }
0118 
0119 static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
0120         unsigned int fmt)
0121 {
0122     /* interface format */
0123     switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0124     case SND_SOC_DAIFMT_I2S:
0125         pxa_i2s.fmt = 0;
0126         break;
0127     case SND_SOC_DAIFMT_LEFT_J:
0128         pxa_i2s.fmt = SACR1_AMSL;
0129         break;
0130     }
0131 
0132     switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0133     case SND_SOC_DAIFMT_BP_FP:
0134         pxa_i2s.master = 1;
0135         break;
0136     case SND_SOC_DAIFMT_BC_FP:
0137         pxa_i2s.master = 0;
0138         break;
0139     default:
0140         break;
0141     }
0142     return 0;
0143 }
0144 
0145 static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
0146         int clk_id, unsigned int freq, int dir)
0147 {
0148     if (clk_id != PXA2XX_I2S_SYSCLK)
0149         return -ENODEV;
0150 
0151     return 0;
0152 }
0153 
0154 static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
0155                 struct snd_pcm_hw_params *params,
0156                 struct snd_soc_dai *dai)
0157 {
0158     struct snd_dmaengine_dai_dma_data *dma_data;
0159 
0160     if (WARN_ON(IS_ERR(clk_i2s)))
0161         return -EINVAL;
0162     clk_prepare_enable(clk_i2s);
0163     clk_ena = 1;
0164     pxa_i2s_wait();
0165 
0166     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0167         dma_data = &pxa2xx_i2s_pcm_stereo_out;
0168     else
0169         dma_data = &pxa2xx_i2s_pcm_stereo_in;
0170 
0171     snd_soc_dai_set_dma_data(dai, substream, dma_data);
0172 
0173     /* is port used by another stream */
0174     if (!(SACR0 & SACR0_ENB)) {
0175         writel(0, i2s_reg_base + SACR0);
0176         if (pxa_i2s.master)
0177             writel(readl(i2s_reg_base + SACR0) | (SACR0_BCKD), i2s_reg_base + SACR0);
0178 
0179         writel(readl(i2s_reg_base + SACR0) | (SACR0_RFTH(14) | SACR0_TFTH(1)), i2s_reg_base + SACR0);
0180         writel(readl(i2s_reg_base + SACR1) | (pxa_i2s.fmt), i2s_reg_base + SACR1);
0181     }
0182     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0183         writel(readl(i2s_reg_base + SAIMR) | (SAIMR_TFS), i2s_reg_base + SAIMR);
0184     else
0185         writel(readl(i2s_reg_base + SAIMR) | (SAIMR_RFS), i2s_reg_base + SAIMR);
0186 
0187     switch (params_rate(params)) {
0188     case 8000:
0189         writel(0x48, i2s_reg_base + SADIV);
0190         break;
0191     case 11025:
0192         writel(0x34, i2s_reg_base + SADIV);
0193         break;
0194     case 16000:
0195         writel(0x24, i2s_reg_base + SADIV);
0196         break;
0197     case 22050:
0198         writel(0x1a, i2s_reg_base + SADIV);
0199         break;
0200     case 44100:
0201         writel(0xd, i2s_reg_base + SADIV);
0202         break;
0203     case 48000:
0204         writel(0xc, i2s_reg_base + SADIV);
0205         break;
0206     case 96000: /* not in manual and possibly slightly inaccurate */
0207         writel(0x6, i2s_reg_base + SADIV);
0208         break;
0209     }
0210 
0211     return 0;
0212 }
0213 
0214 static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
0215                   struct snd_soc_dai *dai)
0216 {
0217     int ret = 0;
0218 
0219     switch (cmd) {
0220     case SNDRV_PCM_TRIGGER_START:
0221         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0222             writel(readl(i2s_reg_base + SACR1) & (~SACR1_DRPL), i2s_reg_base + SACR1);
0223         else
0224             writel(readl(i2s_reg_base + SACR1) & (~SACR1_DREC), i2s_reg_base + SACR1);
0225         writel(readl(i2s_reg_base + SACR0) | (SACR0_ENB), i2s_reg_base + SACR0);
0226         break;
0227     case SNDRV_PCM_TRIGGER_RESUME:
0228     case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0229     case SNDRV_PCM_TRIGGER_STOP:
0230     case SNDRV_PCM_TRIGGER_SUSPEND:
0231     case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0232         break;
0233     default:
0234         ret = -EINVAL;
0235     }
0236 
0237     return ret;
0238 }
0239 
0240 static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
0241                 struct snd_soc_dai *dai)
0242 {
0243     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0244         writel(readl(i2s_reg_base + SACR1) | (SACR1_DRPL), i2s_reg_base + SACR1);
0245         writel(readl(i2s_reg_base + SAIMR) & (~SAIMR_TFS), i2s_reg_base + SAIMR);
0246     } else {
0247         writel(readl(i2s_reg_base + SACR1) | (SACR1_DREC), i2s_reg_base + SACR1);
0248         writel(readl(i2s_reg_base + SAIMR) & (~SAIMR_RFS), i2s_reg_base + SAIMR);
0249     }
0250 
0251     if ((readl(i2s_reg_base + SACR1) & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) {
0252         writel(readl(i2s_reg_base + SACR0) & (~SACR0_ENB), i2s_reg_base + SACR0);
0253         pxa_i2s_wait();
0254         if (clk_ena) {
0255             clk_disable_unprepare(clk_i2s);
0256             clk_ena = 0;
0257         }
0258     }
0259 }
0260 
0261 #ifdef CONFIG_PM
0262 static int pxa2xx_soc_pcm_suspend(struct snd_soc_component *component)
0263 {
0264     /* store registers */
0265     pxa_i2s.sacr0 = readl(i2s_reg_base + SACR0);
0266     pxa_i2s.sacr1 = readl(i2s_reg_base + SACR1);
0267     pxa_i2s.saimr = readl(i2s_reg_base + SAIMR);
0268     pxa_i2s.sadiv = readl(i2s_reg_base + SADIV);
0269 
0270     /* deactivate link */
0271     writel(readl(i2s_reg_base + SACR0) & (~SACR0_ENB), i2s_reg_base + SACR0);
0272     pxa_i2s_wait();
0273     return 0;
0274 }
0275 
0276 static int pxa2xx_soc_pcm_resume(struct snd_soc_component *component)
0277 {
0278     pxa_i2s_wait();
0279 
0280     writel(pxa_i2s.sacr0 & ~SACR0_ENB, i2s_reg_base + SACR0);
0281     writel(pxa_i2s.sacr1, i2s_reg_base + SACR1);
0282     writel(pxa_i2s.saimr, i2s_reg_base + SAIMR);
0283     writel(pxa_i2s.sadiv, i2s_reg_base + SADIV);
0284 
0285     writel(pxa_i2s.sacr0, i2s_reg_base + SACR0);
0286 
0287     return 0;
0288 }
0289 
0290 #else
0291 #define pxa2xx_soc_pcm_suspend  NULL
0292 #define pxa2xx_soc_pcm_resume   NULL
0293 #endif
0294 
0295 static int pxa2xx_i2s_probe(struct snd_soc_dai *dai)
0296 {
0297     clk_i2s = clk_get(dai->dev, "I2SCLK");
0298     if (IS_ERR(clk_i2s))
0299         return PTR_ERR(clk_i2s);
0300 
0301     /*
0302      * PXA Developer's Manual:
0303      * If SACR0[ENB] is toggled in the middle of a normal operation,
0304      * the SACR0[RST] bit must also be set and cleared to reset all
0305      * I2S controller registers.
0306      */
0307     writel(SACR0_RST, i2s_reg_base + SACR0);
0308     writel(0, i2s_reg_base + SACR0);
0309     /* Make sure RPL and REC are disabled */
0310     writel(SACR1_DRPL | SACR1_DREC, i2s_reg_base + SACR1);
0311     /* Along with FIFO servicing */
0312     writel(readl(i2s_reg_base + SAIMR) & (~(SAIMR_RFS | SAIMR_TFS)), i2s_reg_base + SAIMR);
0313 
0314     snd_soc_dai_init_dma_data(dai, &pxa2xx_i2s_pcm_stereo_out,
0315         &pxa2xx_i2s_pcm_stereo_in);
0316 
0317     return 0;
0318 }
0319 
0320 static int  pxa2xx_i2s_remove(struct snd_soc_dai *dai)
0321 {
0322     clk_put(clk_i2s);
0323     clk_i2s = ERR_PTR(-ENOENT);
0324     return 0;
0325 }
0326 
0327 #define PXA2XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
0328         SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
0329         SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
0330 
0331 static const struct snd_soc_dai_ops pxa_i2s_dai_ops = {
0332     .startup    = pxa2xx_i2s_startup,
0333     .shutdown   = pxa2xx_i2s_shutdown,
0334     .trigger    = pxa2xx_i2s_trigger,
0335     .hw_params  = pxa2xx_i2s_hw_params,
0336     .set_fmt    = pxa2xx_i2s_set_dai_fmt,
0337     .set_sysclk = pxa2xx_i2s_set_dai_sysclk,
0338 };
0339 
0340 static struct snd_soc_dai_driver pxa_i2s_dai = {
0341     .probe = pxa2xx_i2s_probe,
0342     .remove = pxa2xx_i2s_remove,
0343     .playback = {
0344         .channels_min = 2,
0345         .channels_max = 2,
0346         .rates = PXA2XX_I2S_RATES,
0347         .formats = SNDRV_PCM_FMTBIT_S16_LE,},
0348     .capture = {
0349         .channels_min = 2,
0350         .channels_max = 2,
0351         .rates = PXA2XX_I2S_RATES,
0352         .formats = SNDRV_PCM_FMTBIT_S16_LE,},
0353     .ops = &pxa_i2s_dai_ops,
0354     .symmetric_rate = 1,
0355 };
0356 
0357 static const struct snd_soc_component_driver pxa_i2s_component = {
0358     .name           = "pxa-i2s",
0359     .pcm_construct      = pxa2xx_soc_pcm_new,
0360     .open           = pxa2xx_soc_pcm_open,
0361     .close          = pxa2xx_soc_pcm_close,
0362     .hw_params      = pxa2xx_soc_pcm_hw_params,
0363     .prepare        = pxa2xx_soc_pcm_prepare,
0364     .trigger        = pxa2xx_soc_pcm_trigger,
0365     .pointer        = pxa2xx_soc_pcm_pointer,
0366     .suspend        = pxa2xx_soc_pcm_suspend,
0367     .resume         = pxa2xx_soc_pcm_resume,
0368     .legacy_dai_naming  = 1,
0369 };
0370 
0371 static int pxa2xx_i2s_drv_probe(struct platform_device *pdev)
0372 {
0373     struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0374 
0375     if (!res) {
0376         dev_err(&pdev->dev, "missing MMIO resource\n");
0377         return -ENXIO;
0378     }
0379 
0380     i2s_reg_base = devm_ioremap_resource(&pdev->dev, res);
0381     if (IS_ERR(i2s_reg_base)) {
0382         dev_err(&pdev->dev, "ioremap failed\n");
0383         return PTR_ERR(i2s_reg_base);
0384     }
0385 
0386     pxa2xx_i2s_pcm_stereo_out.addr = res->start + SADR;
0387     pxa2xx_i2s_pcm_stereo_in.addr = res->start + SADR;
0388 
0389     return devm_snd_soc_register_component(&pdev->dev, &pxa_i2s_component,
0390                            &pxa_i2s_dai, 1);
0391 }
0392 
0393 static struct platform_driver pxa2xx_i2s_driver = {
0394     .probe = pxa2xx_i2s_drv_probe,
0395 
0396     .driver = {
0397         .name = "pxa2xx-i2s",
0398     },
0399 };
0400 
0401 static int __init pxa2xx_i2s_init(void)
0402 {
0403     clk_i2s = ERR_PTR(-ENOENT);
0404     return platform_driver_register(&pxa2xx_i2s_driver);
0405 }
0406 
0407 static void __exit pxa2xx_i2s_exit(void)
0408 {
0409     platform_driver_unregister(&pxa2xx_i2s_driver);
0410 }
0411 
0412 module_init(pxa2xx_i2s_init);
0413 module_exit(pxa2xx_i2s_exit);
0414 
0415 /* Module information */
0416 MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
0417 MODULE_DESCRIPTION("pxa2xx I2S SoC Interface");
0418 MODULE_LICENSE("GPL");
0419 MODULE_ALIAS("platform:pxa2xx-i2s");