xref: /openbmc/linux/sound/soc/pxa/pxa2xx-i2s.c (revision 97e6ea6d)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * pxa2xx-i2s.c  --  ALSA Soc Audio Layer
4  *
5  * Copyright 2005 Wolfson Microelectronics PLC.
6  * Author: Liam Girdwood
7  *         lrg@slimlogic.co.uk
8  */
9 
10 #include <linux/init.h>
11 #include <linux/module.h>
12 #include <linux/device.h>
13 #include <linux/delay.h>
14 #include <linux/clk.h>
15 #include <linux/platform_device.h>
16 #include <linux/io.h>
17 #include <sound/core.h>
18 #include <sound/pcm.h>
19 #include <sound/initval.h>
20 #include <sound/soc.h>
21 #include <sound/pxa2xx-lib.h>
22 #include <sound/dmaengine_pcm.h>
23 
24 #include <mach/hardware.h>
25 #include <mach/audio.h>
26 
27 #include "pxa2xx-i2s.h"
28 
29 /*
30  * I2S Controller Register and Bit Definitions
31  */
32 #define SACR0		__REG(0x40400000)  /* Global Control Register */
33 #define SACR1		__REG(0x40400004)  /* Serial Audio I 2 S/MSB-Justified Control Register */
34 #define SASR0		__REG(0x4040000C)  /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
35 #define SAIMR		__REG(0x40400014)  /* Serial Audio Interrupt Mask Register */
36 #define SAICR		__REG(0x40400018)  /* Serial Audio Interrupt Clear Register */
37 #define SADIV		__REG(0x40400060)  /* Audio Clock Divider Register. */
38 #define SADR		__REG(0x40400080)  /* Serial Audio Data Register (TX and RX FIFO access Register). */
39 
40 #define SACR0_RFTH(x)	((x) << 12)	/* Rx FIFO Interrupt or DMA Trigger Threshold */
41 #define SACR0_TFTH(x)	((x) << 8)	/* Tx FIFO Interrupt or DMA Trigger Threshold */
42 #define SACR0_STRF	(1 << 5)	/* FIFO Select for EFWR Special Function */
43 #define SACR0_EFWR	(1 << 4)	/* Enable EFWR Function  */
44 #define SACR0_RST	(1 << 3)	/* FIFO, i2s Register Reset */
45 #define SACR0_BCKD	(1 << 2)	/* Bit Clock Direction */
46 #define SACR0_ENB	(1 << 0)	/* Enable I2S Link */
47 #define SACR1_ENLBF	(1 << 5)	/* Enable Loopback */
48 #define SACR1_DRPL	(1 << 4)	/* Disable Replaying Function */
49 #define SACR1_DREC	(1 << 3)	/* Disable Recording Function */
50 #define SACR1_AMSL	(1 << 0)	/* Specify Alternate Mode */
51 
52 #define SASR0_I2SOFF	(1 << 7)	/* Controller Status */
53 #define SASR0_ROR	(1 << 6)	/* Rx FIFO Overrun */
54 #define SASR0_TUR	(1 << 5)	/* Tx FIFO Underrun */
55 #define SASR0_RFS	(1 << 4)	/* Rx FIFO Service Request */
56 #define SASR0_TFS	(1 << 3)	/* Tx FIFO Service Request */
57 #define SASR0_BSY	(1 << 2)	/* I2S Busy */
58 #define SASR0_RNE	(1 << 1)	/* Rx FIFO Not Empty */
59 #define SASR0_TNF	(1 << 0)	/* Tx FIFO Not Empty */
60 
61 #define SAICR_ROR	(1 << 6)	/* Clear Rx FIFO Overrun Interrupt */
62 #define SAICR_TUR	(1 << 5)	/* Clear Tx FIFO Underrun Interrupt */
63 
64 #define SAIMR_ROR	(1 << 6)	/* Enable Rx FIFO Overrun Condition Interrupt */
65 #define SAIMR_TUR	(1 << 5)	/* Enable Tx FIFO Underrun Condition Interrupt */
66 #define SAIMR_RFS	(1 << 4)	/* Enable Rx FIFO Service Interrupt */
67 #define SAIMR_TFS	(1 << 3)	/* Enable Tx FIFO Service Interrupt */
68 
69 struct pxa_i2s_port {
70 	u32 sadiv;
71 	u32 sacr0;
72 	u32 sacr1;
73 	u32 saimr;
74 	int master;
75 	u32 fmt;
76 };
77 static struct pxa_i2s_port pxa_i2s;
78 static struct clk *clk_i2s;
79 static int clk_ena = 0;
80 
81 static struct snd_dmaengine_dai_dma_data pxa2xx_i2s_pcm_stereo_out = {
82 	.addr		= __PREG(SADR),
83 	.addr_width	= DMA_SLAVE_BUSWIDTH_4_BYTES,
84 	.chan_name	= "tx",
85 	.maxburst	= 32,
86 };
87 
88 static struct snd_dmaengine_dai_dma_data pxa2xx_i2s_pcm_stereo_in = {
89 	.addr		= __PREG(SADR),
90 	.addr_width	= DMA_SLAVE_BUSWIDTH_4_BYTES,
91 	.chan_name	= "rx",
92 	.maxburst	= 32,
93 };
94 
95 static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
96 			      struct snd_soc_dai *dai)
97 {
98 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
99 	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
100 
101 	if (IS_ERR(clk_i2s))
102 		return PTR_ERR(clk_i2s);
103 
104 	if (!snd_soc_dai_active(cpu_dai))
105 		SACR0 = 0;
106 
107 	return 0;
108 }
109 
110 /* wait for I2S controller to be ready */
111 static int pxa_i2s_wait(void)
112 {
113 	int i;
114 
115 	/* flush the Rx FIFO */
116 	for (i = 0; i < 16; i++)
117 		SADR;
118 	return 0;
119 }
120 
121 static int pxa2xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
122 		unsigned int fmt)
123 {
124 	/* interface format */
125 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
126 	case SND_SOC_DAIFMT_I2S:
127 		pxa_i2s.fmt = 0;
128 		break;
129 	case SND_SOC_DAIFMT_LEFT_J:
130 		pxa_i2s.fmt = SACR1_AMSL;
131 		break;
132 	}
133 
134 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
135 	case SND_SOC_DAIFMT_CBS_CFS:
136 		pxa_i2s.master = 1;
137 		break;
138 	case SND_SOC_DAIFMT_CBM_CFS:
139 		pxa_i2s.master = 0;
140 		break;
141 	default:
142 		break;
143 	}
144 	return 0;
145 }
146 
147 static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
148 		int clk_id, unsigned int freq, int dir)
149 {
150 	if (clk_id != PXA2XX_I2S_SYSCLK)
151 		return -ENODEV;
152 
153 	return 0;
154 }
155 
156 static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
157 				struct snd_pcm_hw_params *params,
158 				struct snd_soc_dai *dai)
159 {
160 	struct snd_dmaengine_dai_dma_data *dma_data;
161 
162 	if (WARN_ON(IS_ERR(clk_i2s)))
163 		return -EINVAL;
164 	clk_prepare_enable(clk_i2s);
165 	clk_ena = 1;
166 	pxa_i2s_wait();
167 
168 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
169 		dma_data = &pxa2xx_i2s_pcm_stereo_out;
170 	else
171 		dma_data = &pxa2xx_i2s_pcm_stereo_in;
172 
173 	snd_soc_dai_set_dma_data(dai, substream, dma_data);
174 
175 	/* is port used by another stream */
176 	if (!(SACR0 & SACR0_ENB)) {
177 		SACR0 = 0;
178 		if (pxa_i2s.master)
179 			SACR0 |= SACR0_BCKD;
180 
181 		SACR0 |= SACR0_RFTH(14) | SACR0_TFTH(1);
182 		SACR1 |= pxa_i2s.fmt;
183 	}
184 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
185 		SAIMR |= SAIMR_TFS;
186 	else
187 		SAIMR |= SAIMR_RFS;
188 
189 	switch (params_rate(params)) {
190 	case 8000:
191 		SADIV = 0x48;
192 		break;
193 	case 11025:
194 		SADIV = 0x34;
195 		break;
196 	case 16000:
197 		SADIV = 0x24;
198 		break;
199 	case 22050:
200 		SADIV = 0x1a;
201 		break;
202 	case 44100:
203 		SADIV = 0xd;
204 		break;
205 	case 48000:
206 		SADIV = 0xc;
207 		break;
208 	case 96000: /* not in manual and possibly slightly inaccurate */
209 		SADIV = 0x6;
210 		break;
211 	}
212 
213 	return 0;
214 }
215 
216 static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
217 			      struct snd_soc_dai *dai)
218 {
219 	int ret = 0;
220 
221 	switch (cmd) {
222 	case SNDRV_PCM_TRIGGER_START:
223 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
224 			SACR1 &= ~SACR1_DRPL;
225 		else
226 			SACR1 &= ~SACR1_DREC;
227 		SACR0 |= SACR0_ENB;
228 		break;
229 	case SNDRV_PCM_TRIGGER_RESUME:
230 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
231 	case SNDRV_PCM_TRIGGER_STOP:
232 	case SNDRV_PCM_TRIGGER_SUSPEND:
233 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
234 		break;
235 	default:
236 		ret = -EINVAL;
237 	}
238 
239 	return ret;
240 }
241 
242 static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
243 				struct snd_soc_dai *dai)
244 {
245 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
246 		SACR1 |= SACR1_DRPL;
247 		SAIMR &= ~SAIMR_TFS;
248 	} else {
249 		SACR1 |= SACR1_DREC;
250 		SAIMR &= ~SAIMR_RFS;
251 	}
252 
253 	if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) {
254 		SACR0 &= ~SACR0_ENB;
255 		pxa_i2s_wait();
256 		if (clk_ena) {
257 			clk_disable_unprepare(clk_i2s);
258 			clk_ena = 0;
259 		}
260 	}
261 }
262 
263 #ifdef CONFIG_PM
264 static int pxa2xx_soc_pcm_suspend(struct snd_soc_component *component)
265 {
266 	/* store registers */
267 	pxa_i2s.sacr0 = SACR0;
268 	pxa_i2s.sacr1 = SACR1;
269 	pxa_i2s.saimr = SAIMR;
270 	pxa_i2s.sadiv = SADIV;
271 
272 	/* deactivate link */
273 	SACR0 &= ~SACR0_ENB;
274 	pxa_i2s_wait();
275 	return 0;
276 }
277 
278 static int pxa2xx_soc_pcm_resume(struct snd_soc_component *component)
279 {
280 	pxa_i2s_wait();
281 
282 	SACR0 = pxa_i2s.sacr0 & ~SACR0_ENB;
283 	SACR1 = pxa_i2s.sacr1;
284 	SAIMR = pxa_i2s.saimr;
285 	SADIV = pxa_i2s.sadiv;
286 
287 	SACR0 = pxa_i2s.sacr0;
288 
289 	return 0;
290 }
291 
292 #else
293 #define pxa2xx_soc_pcm_suspend	NULL
294 #define pxa2xx_soc_pcm_resume	NULL
295 #endif
296 
297 static int pxa2xx_i2s_probe(struct snd_soc_dai *dai)
298 {
299 	clk_i2s = clk_get(dai->dev, "I2SCLK");
300 	if (IS_ERR(clk_i2s))
301 		return PTR_ERR(clk_i2s);
302 
303 	/*
304 	 * PXA Developer's Manual:
305 	 * If SACR0[ENB] is toggled in the middle of a normal operation,
306 	 * the SACR0[RST] bit must also be set and cleared to reset all
307 	 * I2S controller registers.
308 	 */
309 	SACR0 = SACR0_RST;
310 	SACR0 = 0;
311 	/* Make sure RPL and REC are disabled */
312 	SACR1 = SACR1_DRPL | SACR1_DREC;
313 	/* Along with FIFO servicing */
314 	SAIMR &= ~(SAIMR_RFS | SAIMR_TFS);
315 
316 	snd_soc_dai_init_dma_data(dai, &pxa2xx_i2s_pcm_stereo_out,
317 		&pxa2xx_i2s_pcm_stereo_in);
318 
319 	return 0;
320 }
321 
322 static int  pxa2xx_i2s_remove(struct snd_soc_dai *dai)
323 {
324 	clk_put(clk_i2s);
325 	clk_i2s = ERR_PTR(-ENOENT);
326 	return 0;
327 }
328 
329 #define PXA2XX_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
330 		SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
331 		SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
332 
333 static const struct snd_soc_dai_ops pxa_i2s_dai_ops = {
334 	.startup	= pxa2xx_i2s_startup,
335 	.shutdown	= pxa2xx_i2s_shutdown,
336 	.trigger	= pxa2xx_i2s_trigger,
337 	.hw_params	= pxa2xx_i2s_hw_params,
338 	.set_fmt	= pxa2xx_i2s_set_dai_fmt,
339 	.set_sysclk	= pxa2xx_i2s_set_dai_sysclk,
340 };
341 
342 static struct snd_soc_dai_driver pxa_i2s_dai = {
343 	.probe = pxa2xx_i2s_probe,
344 	.remove = pxa2xx_i2s_remove,
345 	.playback = {
346 		.channels_min = 2,
347 		.channels_max = 2,
348 		.rates = PXA2XX_I2S_RATES,
349 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
350 	.capture = {
351 		.channels_min = 2,
352 		.channels_max = 2,
353 		.rates = PXA2XX_I2S_RATES,
354 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
355 	.ops = &pxa_i2s_dai_ops,
356 	.symmetric_rate = 1,
357 };
358 
359 static const struct snd_soc_component_driver pxa_i2s_component = {
360 	.name		= "pxa-i2s",
361 	.pcm_construct	= pxa2xx_soc_pcm_new,
362 	.open		= pxa2xx_soc_pcm_open,
363 	.close		= pxa2xx_soc_pcm_close,
364 	.hw_params	= pxa2xx_soc_pcm_hw_params,
365 	.prepare	= pxa2xx_soc_pcm_prepare,
366 	.trigger	= pxa2xx_soc_pcm_trigger,
367 	.pointer	= pxa2xx_soc_pcm_pointer,
368 	.suspend	= pxa2xx_soc_pcm_suspend,
369 	.resume		= pxa2xx_soc_pcm_resume,
370 };
371 
372 static int pxa2xx_i2s_drv_probe(struct platform_device *pdev)
373 {
374 	return devm_snd_soc_register_component(&pdev->dev, &pxa_i2s_component,
375 					       &pxa_i2s_dai, 1);
376 }
377 
378 static struct platform_driver pxa2xx_i2s_driver = {
379 	.probe = pxa2xx_i2s_drv_probe,
380 
381 	.driver = {
382 		.name = "pxa2xx-i2s",
383 	},
384 };
385 
386 static int __init pxa2xx_i2s_init(void)
387 {
388 	clk_i2s = ERR_PTR(-ENOENT);
389 	return platform_driver_register(&pxa2xx_i2s_driver);
390 }
391 
392 static void __exit pxa2xx_i2s_exit(void)
393 {
394 	platform_driver_unregister(&pxa2xx_i2s_driver);
395 }
396 
397 module_init(pxa2xx_i2s_init);
398 module_exit(pxa2xx_i2s_exit);
399 
400 /* Module information */
401 MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
402 MODULE_DESCRIPTION("pxa2xx I2S SoC Interface");
403 MODULE_LICENSE("GPL");
404 MODULE_ALIAS("platform:pxa2xx-i2s");
405