0001
0002
0003
0004
0005
0006
0007
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
0030
0031 #define SACR0 (0x0000)
0032 #define SACR1 (0x0004)
0033 #define SASR0 (0x000C)
0034 #define SAIMR (0x0014)
0035 #define SAICR (0x0018)
0036 #define SADIV (0x0060)
0037 #define SADR (0x0080)
0038
0039 #define SACR0_RFTH(x) ((x) << 12)
0040 #define SACR0_TFTH(x) ((x) << 8)
0041 #define SACR0_STRF (1 << 5)
0042 #define SACR0_EFWR (1 << 4)
0043 #define SACR0_RST (1 << 3)
0044 #define SACR0_BCKD (1 << 2)
0045 #define SACR0_ENB (1 << 0)
0046 #define SACR1_ENLBF (1 << 5)
0047 #define SACR1_DRPL (1 << 4)
0048 #define SACR1_DREC (1 << 3)
0049 #define SACR1_AMSL (1 << 0)
0050
0051 #define SASR0_I2SOFF (1 << 7)
0052 #define SASR0_ROR (1 << 6)
0053 #define SASR0_TUR (1 << 5)
0054 #define SASR0_RFS (1 << 4)
0055 #define SASR0_TFS (1 << 3)
0056 #define SASR0_BSY (1 << 2)
0057 #define SASR0_RNE (1 << 1)
0058 #define SASR0_TNF (1 << 0)
0059
0060 #define SAICR_ROR (1 << 6)
0061 #define SAICR_TUR (1 << 5)
0062
0063 #define SAIMR_ROR (1 << 6)
0064 #define SAIMR_TUR (1 << 5)
0065 #define SAIMR_RFS (1 << 4)
0066 #define SAIMR_TFS (1 << 3)
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
0109 static int pxa_i2s_wait(void)
0110 {
0111 int i;
0112
0113
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
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
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:
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
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
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
0303
0304
0305
0306
0307 writel(SACR0_RST, i2s_reg_base + SACR0);
0308 writel(0, i2s_reg_base + SACR0);
0309
0310 writel(SACR1_DRPL | SACR1_DREC, i2s_reg_base + SACR1);
0311
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
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");