1 /*
2  * linux/sound/soc/ep93xx-i2s.c
3  * EP93xx I2S driver
4  *
5  * Copyright (C) 2010 Ryan Mallon
6  *
7  * Based on the original driver by:
8  *   Copyright (C) 2007 Chase Douglas <chasedouglas@gmail>
9  *   Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  *
15  */
16 
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/slab.h>
20 #include <linux/clk.h>
21 #include <linux/io.h>
22 
23 #include <sound/core.h>
24 #include <sound/pcm.h>
25 #include <sound/pcm_params.h>
26 #include <sound/initval.h>
27 #include <sound/soc.h>
28 
29 #include <mach/hardware.h>
30 #include <mach/ep93xx-regs.h>
31 #include <mach/dma.h>
32 
33 #include "ep93xx-pcm.h"
34 
35 #define EP93XX_I2S_TXCLKCFG		0x00
36 #define EP93XX_I2S_RXCLKCFG		0x04
37 #define EP93XX_I2S_GLCTRL		0x0C
38 
39 #define EP93XX_I2S_TXLINCTRLDATA	0x28
40 #define EP93XX_I2S_TXCTRL		0x2C
41 #define EP93XX_I2S_TXWRDLEN		0x30
42 #define EP93XX_I2S_TX0EN		0x34
43 
44 #define EP93XX_I2S_RXLINCTRLDATA	0x58
45 #define EP93XX_I2S_RXCTRL		0x5C
46 #define EP93XX_I2S_RXWRDLEN		0x60
47 #define EP93XX_I2S_RX0EN		0x64
48 
49 #define EP93XX_I2S_WRDLEN_16		(0 << 0)
50 #define EP93XX_I2S_WRDLEN_24		(1 << 0)
51 #define EP93XX_I2S_WRDLEN_32		(2 << 0)
52 
53 #define EP93XX_I2S_LINCTRLDATA_R_JUST	(1 << 2) /* Right justify */
54 
55 #define EP93XX_I2S_CLKCFG_LRS		(1 << 0) /* lrclk polarity */
56 #define EP93XX_I2S_CLKCFG_CKP		(1 << 1) /* Bit clock polarity */
57 #define EP93XX_I2S_CLKCFG_REL		(1 << 2) /* First bit transition */
58 #define EP93XX_I2S_CLKCFG_MASTER	(1 << 3) /* Master mode */
59 #define EP93XX_I2S_CLKCFG_NBCG		(1 << 4) /* Not bit clock gating */
60 
61 struct ep93xx_i2s_info {
62 	struct clk			*mclk;
63 	struct clk			*sclk;
64 	struct clk			*lrclk;
65 	struct ep93xx_pcm_dma_params	*dma_params;
66 	struct resource			*mem;
67 	void __iomem			*regs;
68 };
69 
70 struct ep93xx_pcm_dma_params ep93xx_i2s_dma_params[] = {
71 	[SNDRV_PCM_STREAM_PLAYBACK] = {
72 		.name		= "i2s-pcm-out",
73 		.dma_port	= EP93XX_DMA_I2S1,
74 	},
75 	[SNDRV_PCM_STREAM_CAPTURE] = {
76 		.name		= "i2s-pcm-in",
77 		.dma_port	= EP93XX_DMA_I2S1,
78 	},
79 };
80 
ep93xx_i2s_write_reg(struct ep93xx_i2s_info * info,unsigned reg,unsigned val)81 static inline void ep93xx_i2s_write_reg(struct ep93xx_i2s_info *info,
82 					unsigned reg, unsigned val)
83 {
84 	__raw_writel(val, info->regs + reg);
85 }
86 
ep93xx_i2s_read_reg(struct ep93xx_i2s_info * info,unsigned reg)87 static inline unsigned ep93xx_i2s_read_reg(struct ep93xx_i2s_info *info,
88 					   unsigned reg)
89 {
90 	return __raw_readl(info->regs + reg);
91 }
92 
ep93xx_i2s_enable(struct ep93xx_i2s_info * info,int stream)93 static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream)
94 {
95 	unsigned base_reg;
96 	int i;
97 
98 	if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
99 	    (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
100 		/* Enable clocks */
101 		clk_enable(info->mclk);
102 		clk_enable(info->sclk);
103 		clk_enable(info->lrclk);
104 
105 		/* Enable i2s */
106 		ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 1);
107 	}
108 
109 	/* Enable fifos */
110 	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
111 		base_reg = EP93XX_I2S_TX0EN;
112 	else
113 		base_reg = EP93XX_I2S_RX0EN;
114 	for (i = 0; i < 3; i++)
115 		ep93xx_i2s_write_reg(info, base_reg + (i * 4), 1);
116 }
117 
ep93xx_i2s_disable(struct ep93xx_i2s_info * info,int stream)118 static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
119 {
120 	unsigned base_reg;
121 	int i;
122 
123 	/* Disable fifos */
124 	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
125 		base_reg = EP93XX_I2S_TX0EN;
126 	else
127 		base_reg = EP93XX_I2S_RX0EN;
128 	for (i = 0; i < 3; i++)
129 		ep93xx_i2s_write_reg(info, base_reg + (i * 4), 0);
130 
131 	if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
132 	    (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
133 		/* Disable i2s */
134 		ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 0);
135 
136 		/* Disable clocks */
137 		clk_disable(info->lrclk);
138 		clk_disable(info->sclk);
139 		clk_disable(info->mclk);
140 	}
141 }
142 
ep93xx_i2s_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)143 static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,
144 			      struct snd_soc_dai *dai)
145 {
146 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
147 	struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
148 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
149 
150 	snd_soc_dai_set_dma_data(cpu_dai, substream,
151 				 &info->dma_params[substream->stream]);
152 	return 0;
153 }
154 
ep93xx_i2s_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)155 static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream,
156 				struct snd_soc_dai *dai)
157 {
158 	struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
159 
160 	ep93xx_i2s_disable(info, substream->stream);
161 }
162 
ep93xx_i2s_set_dai_fmt(struct snd_soc_dai * cpu_dai,unsigned int fmt)163 static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
164 				  unsigned int fmt)
165 {
166 	struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai);
167 	unsigned int clk_cfg, lin_ctrl;
168 
169 	clk_cfg  = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG);
170 	lin_ctrl = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXLINCTRLDATA);
171 
172 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
173 	case SND_SOC_DAIFMT_I2S:
174 		clk_cfg |= EP93XX_I2S_CLKCFG_REL;
175 		lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST;
176 		break;
177 
178 	case SND_SOC_DAIFMT_LEFT_J:
179 		clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
180 		lin_ctrl &= ~EP93XX_I2S_LINCTRLDATA_R_JUST;
181 		break;
182 
183 	case SND_SOC_DAIFMT_RIGHT_J:
184 		clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
185 		lin_ctrl |= EP93XX_I2S_LINCTRLDATA_R_JUST;
186 		break;
187 
188 	default:
189 		return -EINVAL;
190 	}
191 
192 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
193 	case SND_SOC_DAIFMT_CBS_CFS:
194 		/* CPU is master */
195 		clk_cfg |= EP93XX_I2S_CLKCFG_MASTER;
196 		break;
197 
198 	case SND_SOC_DAIFMT_CBM_CFM:
199 		/* Codec is master */
200 		clk_cfg &= ~EP93XX_I2S_CLKCFG_MASTER;
201 		break;
202 
203 	default:
204 		return -EINVAL;
205 	}
206 
207 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
208 	case SND_SOC_DAIFMT_NB_NF:
209 		/* Negative bit clock, lrclk low on left word */
210 		clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL);
211 		break;
212 
213 	case SND_SOC_DAIFMT_NB_IF:
214 		/* Negative bit clock, lrclk low on right word */
215 		clk_cfg &= ~EP93XX_I2S_CLKCFG_CKP;
216 		clk_cfg |= EP93XX_I2S_CLKCFG_REL;
217 		break;
218 
219 	case SND_SOC_DAIFMT_IB_NF:
220 		/* Positive bit clock, lrclk low on left word */
221 		clk_cfg |= EP93XX_I2S_CLKCFG_CKP;
222 		clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;
223 		break;
224 
225 	case SND_SOC_DAIFMT_IB_IF:
226 		/* Positive bit clock, lrclk low on right word */
227 		clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_REL;
228 		break;
229 	}
230 
231 	/* Write new register values */
232 	ep93xx_i2s_write_reg(info, EP93XX_I2S_RXCLKCFG, clk_cfg);
233 	ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCLKCFG, clk_cfg);
234 	ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, lin_ctrl);
235 	ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, lin_ctrl);
236 	return 0;
237 }
238 
ep93xx_i2s_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)239 static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,
240 				struct snd_pcm_hw_params *params,
241 				struct snd_soc_dai *dai)
242 {
243 	struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
244 	unsigned word_len, div, sdiv, lrdiv;
245 	int err;
246 
247 	switch (params_format(params)) {
248 	case SNDRV_PCM_FORMAT_S16_LE:
249 		word_len = EP93XX_I2S_WRDLEN_16;
250 		break;
251 
252 	case SNDRV_PCM_FORMAT_S24_LE:
253 		word_len = EP93XX_I2S_WRDLEN_24;
254 		break;
255 
256 	case SNDRV_PCM_FORMAT_S32_LE:
257 		word_len = EP93XX_I2S_WRDLEN_32;
258 		break;
259 
260 	default:
261 		return -EINVAL;
262 	}
263 
264 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
265 		ep93xx_i2s_write_reg(info, EP93XX_I2S_TXWRDLEN, word_len);
266 	else
267 		ep93xx_i2s_write_reg(info, EP93XX_I2S_RXWRDLEN, word_len);
268 
269 	/*
270 	 * EP93xx I2S module can be setup so SCLK / LRCLK value can be
271 	 * 32, 64, 128. MCLK / SCLK value can be 2 and 4.
272 	 * We set LRCLK equal to `rate' and minimum SCLK / LRCLK
273 	 * value is 64, because our sample size is 32 bit * 2 channels.
274 	 * I2S standard permits us to transmit more bits than
275 	 * the codec uses.
276 	 */
277 	div = clk_get_rate(info->mclk) / params_rate(params);
278 	sdiv = 4;
279 	if (div > (256 + 512) / 2) {
280 		lrdiv = 128;
281 	} else {
282 		lrdiv = 64;
283 		if (div < (128 + 256) / 2)
284 			sdiv = 2;
285 	}
286 
287 	err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv);
288 	if (err)
289 		return err;
290 
291 	err = clk_set_rate(info->lrclk, clk_get_rate(info->sclk) / lrdiv);
292 	if (err)
293 		return err;
294 
295 	ep93xx_i2s_enable(info, substream->stream);
296 	return 0;
297 }
298 
ep93xx_i2s_set_sysclk(struct snd_soc_dai * cpu_dai,int clk_id,unsigned int freq,int dir)299 static int ep93xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,
300 				 unsigned int freq, int dir)
301 {
302 	struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai);
303 
304 	if (dir == SND_SOC_CLOCK_IN || clk_id != 0)
305 		return -EINVAL;
306 
307 	return clk_set_rate(info->mclk, freq);
308 }
309 
310 #ifdef CONFIG_PM
ep93xx_i2s_suspend(struct snd_soc_dai * dai)311 static int ep93xx_i2s_suspend(struct snd_soc_dai *dai)
312 {
313 	struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
314 
315 	if (!dai->active)
316 		return 0;
317 
318 	ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK);
319 	ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE);
320 
321 	return 0;
322 }
323 
ep93xx_i2s_resume(struct snd_soc_dai * dai)324 static int ep93xx_i2s_resume(struct snd_soc_dai *dai)
325 {
326 	struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);
327 
328 	if (!dai->active)
329 		return 0;
330 
331 	ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK);
332 	ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE);
333 
334 	return 0;
335 }
336 #else
337 #define ep93xx_i2s_suspend	NULL
338 #define ep93xx_i2s_resume	NULL
339 #endif
340 
341 static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {
342 	.startup	= ep93xx_i2s_startup,
343 	.shutdown	= ep93xx_i2s_shutdown,
344 	.hw_params	= ep93xx_i2s_hw_params,
345 	.set_sysclk	= ep93xx_i2s_set_sysclk,
346 	.set_fmt	= ep93xx_i2s_set_dai_fmt,
347 };
348 
349 #define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
350 
351 static struct snd_soc_dai_driver ep93xx_i2s_dai = {
352 	.symmetric_rates= 1,
353 	.suspend	= ep93xx_i2s_suspend,
354 	.resume		= ep93xx_i2s_resume,
355 	.playback	= {
356 		.channels_min	= 2,
357 		.channels_max	= 2,
358 		.rates		= SNDRV_PCM_RATE_8000_192000,
359 		.formats	= EP93XX_I2S_FORMATS,
360 	},
361 	.capture	= {
362 		 .channels_min	= 2,
363 		 .channels_max	= 2,
364 		 .rates		= SNDRV_PCM_RATE_8000_192000,
365 		 .formats	= EP93XX_I2S_FORMATS,
366 	},
367 	.ops		= &ep93xx_i2s_dai_ops,
368 };
369 
ep93xx_i2s_probe(struct platform_device * pdev)370 static int ep93xx_i2s_probe(struct platform_device *pdev)
371 {
372 	struct ep93xx_i2s_info *info;
373 	struct resource *res;
374 	int err;
375 
376 	info = kzalloc(sizeof(struct ep93xx_i2s_info), GFP_KERNEL);
377 	if (!info) {
378 		err = -ENOMEM;
379 		goto fail;
380 	}
381 
382 	dev_set_drvdata(&pdev->dev, info);
383 	info->dma_params = ep93xx_i2s_dma_params;
384 
385 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
386 	if (!res) {
387 		err = -ENODEV;
388 		goto fail_free_info;
389 	}
390 
391 	info->mem = request_mem_region(res->start, resource_size(res),
392 				       pdev->name);
393 	if (!info->mem) {
394 		err = -EBUSY;
395 		goto fail_free_info;
396 	}
397 
398 	info->regs = ioremap(info->mem->start, resource_size(info->mem));
399 	if (!info->regs) {
400 		err = -ENXIO;
401 		goto fail_release_mem;
402 	}
403 
404 	info->mclk = clk_get(&pdev->dev, "mclk");
405 	if (IS_ERR(info->mclk)) {
406 		err = PTR_ERR(info->mclk);
407 		goto fail_unmap_mem;
408 	}
409 
410 	info->sclk = clk_get(&pdev->dev, "sclk");
411 	if (IS_ERR(info->sclk)) {
412 		err = PTR_ERR(info->sclk);
413 		goto fail_put_mclk;
414 	}
415 
416 	info->lrclk = clk_get(&pdev->dev, "lrclk");
417 	if (IS_ERR(info->lrclk)) {
418 		err = PTR_ERR(info->lrclk);
419 		goto fail_put_sclk;
420 	}
421 
422 	err = snd_soc_register_dai(&pdev->dev, &ep93xx_i2s_dai);
423 	if (err)
424 		goto fail_put_lrclk;
425 
426 	return 0;
427 
428 fail_put_lrclk:
429 	clk_put(info->lrclk);
430 fail_put_sclk:
431 	clk_put(info->sclk);
432 fail_put_mclk:
433 	clk_put(info->mclk);
434 fail_unmap_mem:
435 	iounmap(info->regs);
436 fail_release_mem:
437 	release_mem_region(info->mem->start, resource_size(info->mem));
438 fail_free_info:
439 	kfree(info);
440 fail:
441 	return err;
442 }
443 
ep93xx_i2s_remove(struct platform_device * pdev)444 static int __devexit ep93xx_i2s_remove(struct platform_device *pdev)
445 {
446 	struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
447 
448 	snd_soc_unregister_dai(&pdev->dev);
449 	clk_put(info->lrclk);
450 	clk_put(info->sclk);
451 	clk_put(info->mclk);
452 	iounmap(info->regs);
453 	release_mem_region(info->mem->start, resource_size(info->mem));
454 	kfree(info);
455 	return 0;
456 }
457 
458 static struct platform_driver ep93xx_i2s_driver = {
459 	.probe	= ep93xx_i2s_probe,
460 	.remove	= __devexit_p(ep93xx_i2s_remove),
461 	.driver	= {
462 		.name	= "ep93xx-i2s",
463 		.owner	= THIS_MODULE,
464 	},
465 };
466 
467 module_platform_driver(ep93xx_i2s_driver);
468 
469 MODULE_ALIAS("platform:ep93xx-i2s");
470 MODULE_AUTHOR("Ryan Mallon");
471 MODULE_DESCRIPTION("EP93XX I2S driver");
472 MODULE_LICENSE("GPL");
473