aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/bcm/bcm2835-i2s.c
diff options
context:
space:
mode:
authorFlorian Meier <florian.meier@koalo.de>2013-11-22 10:24:08 -0500
committerMark Brown <broonie@linaro.org>2013-11-25 12:17:08 -0500
commitc6aeb7de226dd08ad9b343fc6cbaf2ff36f69c84 (patch)
tree114046b89f43bf7ed16db21140f4d24faa685665 /sound/soc/bcm/bcm2835-i2s.c
parent6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae (diff)
ASoC: Add support for BCM2835
This driver adds support for digital audio (I2S) for the BCM2835 SoC that is used by the Raspberry Pi. External audio codecs can be connected to the Raspberry Pi via P5 header. It relies on cyclic DMA engine support for BCM2835. Signed-off-by: Florian Meier <florian.meier@koalo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/bcm/bcm2835-i2s.c')
-rw-r--r--sound/soc/bcm/bcm2835-i2s.c886
1 files changed, 886 insertions, 0 deletions
diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c
new file mode 100644
index 000000000000..f49b007c8b43
--- /dev/null
+++ b/sound/soc/bcm/bcm2835-i2s.c
@@ -0,0 +1,886 @@
1/*
2 * ALSA SoC I2S Audio Layer for Broadcom BCM2835 SoC
3 *
4 * Author: Florian Meier <florian.meier@koalo.de>
5 * Copyright 2013
6 *
7 * Based on
8 * Raspberry Pi PCM I2S ALSA Driver
9 * Copyright (c) by Phil Poole 2013
10 *
11 * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor
12 * Vladimir Barinov, <vbarinov@embeddedalley.com>
13 * Copyright (C) 2007 MontaVista Software, Inc., <source@mvista.com>
14 *
15 * OMAP ALSA SoC DAI driver using McBSP port
16 * Copyright (C) 2008 Nokia Corporation
17 * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com>
18 * Peter Ujfalusi <peter.ujfalusi@ti.com>
19 *
20 * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver
21 * Author: Timur Tabi <timur@freescale.com>
22 * Copyright 2007-2010 Freescale Semiconductor, Inc.
23 *
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * version 2 as published by the Free Software Foundation.
27 *
28 * This program is distributed in the hope that it will be useful, but
29 * WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
31 * General Public License for more details.
32 */
33
34#include <linux/init.h>
35#include <linux/module.h>
36#include <linux/device.h>
37#include <linux/slab.h>
38#include <linux/delay.h>
39#include <linux/io.h>
40#include <linux/clk.h>
41
42#include <sound/core.h>
43#include <sound/pcm.h>
44#include <sound/pcm_params.h>
45#include <sound/initval.h>
46#include <sound/soc.h>
47#include <sound/dmaengine_pcm.h>
48
49/* Clock registers */
50#define BCM2835_CLK_PCMCTL_REG 0x00
51#define BCM2835_CLK_PCMDIV_REG 0x04
52
53/* Clock register settings */
54#define BCM2835_CLK_PASSWD (0x5a000000)
55#define BCM2835_CLK_PASSWD_MASK (0xff000000)
56#define BCM2835_CLK_MASH(v) ((v) << 9)
57#define BCM2835_CLK_FLIP BIT(8)
58#define BCM2835_CLK_BUSY BIT(7)
59#define BCM2835_CLK_KILL BIT(5)
60#define BCM2835_CLK_ENAB BIT(4)
61#define BCM2835_CLK_SRC(v) (v)
62
63#define BCM2835_CLK_SHIFT (12)
64#define BCM2835_CLK_DIVI(v) ((v) << BCM2835_CLK_SHIFT)
65#define BCM2835_CLK_DIVF(v) (v)
66#define BCM2835_CLK_DIVF_MASK (0xFFF)
67
68enum {
69 BCM2835_CLK_MASH_0 = 0,
70 BCM2835_CLK_MASH_1,
71 BCM2835_CLK_MASH_2,
72 BCM2835_CLK_MASH_3,
73};
74
75enum {
76 BCM2835_CLK_SRC_GND = 0,
77 BCM2835_CLK_SRC_OSC,
78 BCM2835_CLK_SRC_DBG0,
79 BCM2835_CLK_SRC_DBG1,
80 BCM2835_CLK_SRC_PLLA,
81 BCM2835_CLK_SRC_PLLC,
82 BCM2835_CLK_SRC_PLLD,
83 BCM2835_CLK_SRC_HDMI,
84};
85
86/* Most clocks are not useable (freq = 0) */
87static const unsigned int bcm2835_clk_freq[BCM2835_CLK_SRC_HDMI+1] = {
88 [BCM2835_CLK_SRC_GND] = 0,
89 [BCM2835_CLK_SRC_OSC] = 19200000,
90 [BCM2835_CLK_SRC_DBG0] = 0,
91 [BCM2835_CLK_SRC_DBG1] = 0,
92 [BCM2835_CLK_SRC_PLLA] = 0,
93 [BCM2835_CLK_SRC_PLLC] = 0,
94 [BCM2835_CLK_SRC_PLLD] = 500000000,
95 [BCM2835_CLK_SRC_HDMI] = 0,
96};
97
98/* I2S registers */
99#define BCM2835_I2S_CS_A_REG 0x00
100#define BCM2835_I2S_FIFO_A_REG 0x04
101#define BCM2835_I2S_MODE_A_REG 0x08
102#define BCM2835_I2S_RXC_A_REG 0x0c
103#define BCM2835_I2S_TXC_A_REG 0x10
104#define BCM2835_I2S_DREQ_A_REG 0x14
105#define BCM2835_I2S_INTEN_A_REG 0x18
106#define BCM2835_I2S_INTSTC_A_REG 0x1c
107#define BCM2835_I2S_GRAY_REG 0x20
108
109/* I2S register settings */
110#define BCM2835_I2S_STBY BIT(25)
111#define BCM2835_I2S_SYNC BIT(24)
112#define BCM2835_I2S_RXSEX BIT(23)
113#define BCM2835_I2S_RXF BIT(22)
114#define BCM2835_I2S_TXE BIT(21)
115#define BCM2835_I2S_RXD BIT(20)
116#define BCM2835_I2S_TXD BIT(19)
117#define BCM2835_I2S_RXR BIT(18)
118#define BCM2835_I2S_TXW BIT(17)
119#define BCM2835_I2S_CS_RXERR BIT(16)
120#define BCM2835_I2S_CS_TXERR BIT(15)
121#define BCM2835_I2S_RXSYNC BIT(14)
122#define BCM2835_I2S_TXSYNC BIT(13)
123#define BCM2835_I2S_DMAEN BIT(9)
124#define BCM2835_I2S_RXTHR(v) ((v) << 7)
125#define BCM2835_I2S_TXTHR(v) ((v) << 5)
126#define BCM2835_I2S_RXCLR BIT(4)
127#define BCM2835_I2S_TXCLR BIT(3)
128#define BCM2835_I2S_TXON BIT(2)
129#define BCM2835_I2S_RXON BIT(1)
130#define BCM2835_I2S_EN (1)
131
132#define BCM2835_I2S_CLKDIS BIT(28)
133#define BCM2835_I2S_PDMN BIT(27)
134#define BCM2835_I2S_PDME BIT(26)
135#define BCM2835_I2S_FRXP BIT(25)
136#define BCM2835_I2S_FTXP BIT(24)
137#define BCM2835_I2S_CLKM BIT(23)
138#define BCM2835_I2S_CLKI BIT(22)
139#define BCM2835_I2S_FSM BIT(21)
140#define BCM2835_I2S_FSI BIT(20)
141#define BCM2835_I2S_FLEN(v) ((v) << 10)
142#define BCM2835_I2S_FSLEN(v) (v)
143
144#define BCM2835_I2S_CHWEX BIT(15)
145#define BCM2835_I2S_CHEN BIT(14)
146#define BCM2835_I2S_CHPOS(v) ((v) << 4)
147#define BCM2835_I2S_CHWID(v) (v)
148#define BCM2835_I2S_CH1(v) ((v) << 16)
149#define BCM2835_I2S_CH2(v) (v)
150
151#define BCM2835_I2S_TX_PANIC(v) ((v) << 24)
152#define BCM2835_I2S_RX_PANIC(v) ((v) << 16)
153#define BCM2835_I2S_TX(v) ((v) << 8)
154#define BCM2835_I2S_RX(v) (v)
155
156#define BCM2835_I2S_INT_RXERR BIT(3)
157#define BCM2835_I2S_INT_TXERR BIT(2)
158#define BCM2835_I2S_INT_RXR BIT(1)
159#define BCM2835_I2S_INT_TXW BIT(0)
160
161/* I2S DMA interface */
162/* FIXME: Needs IOMMU support */
163#define BCM2835_VCMMU_SHIFT (0x7E000000 - 0x20000000)
164
165/* General device struct */
166struct bcm2835_i2s_dev {
167 struct device *dev;
168 struct snd_dmaengine_dai_dma_data dma_data[2];
169 unsigned int fmt;
170 unsigned int bclk_ratio;
171
172 struct regmap *i2s_regmap;
173 struct regmap *clk_regmap;
174};
175
176static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev)
177{
178 /* Start the clock if in master mode */
179 unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK;
180
181 switch (master) {
182 case SND_SOC_DAIFMT_CBS_CFS:
183 case SND_SOC_DAIFMT_CBS_CFM:
184 regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,
185 BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB,
186 BCM2835_CLK_PASSWD | BCM2835_CLK_ENAB);
187 break;
188 default:
189 break;
190 }
191}
192
193static void bcm2835_i2s_stop_clock(struct bcm2835_i2s_dev *dev)
194{
195 uint32_t clkreg;
196 int timeout = 1000;
197
198 /* Stop clock */
199 regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,
200 BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB,
201 BCM2835_CLK_PASSWD);
202
203 /* Wait for the BUSY flag going down */
204 while (--timeout) {
205 regmap_read(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, &clkreg);
206 if (!(clkreg & BCM2835_CLK_BUSY))
207 break;
208 }
209
210 if (!timeout) {
211 /* KILL the clock */
212 dev_err(dev->dev, "I2S clock didn't stop. Kill the clock!\n");
213 regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,
214 BCM2835_CLK_KILL | BCM2835_CLK_PASSWD_MASK,
215 BCM2835_CLK_KILL | BCM2835_CLK_PASSWD);
216 }
217}
218
219static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev,
220 bool tx, bool rx)
221{
222 int timeout = 1000;
223 uint32_t syncval;
224 uint32_t csreg;
225 uint32_t i2s_active_state;
226 uint32_t clkreg;
227 uint32_t clk_active_state;
228 uint32_t off;
229 uint32_t clr;
230
231 off = tx ? BCM2835_I2S_TXON : 0;
232 off |= rx ? BCM2835_I2S_RXON : 0;
233
234 clr = tx ? BCM2835_I2S_TXCLR : 0;
235 clr |= rx ? BCM2835_I2S_RXCLR : 0;
236
237 /* Backup the current state */
238 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg);
239 i2s_active_state = csreg & (BCM2835_I2S_RXON | BCM2835_I2S_TXON);
240
241 regmap_read(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, &clkreg);
242 clk_active_state = clkreg & BCM2835_CLK_ENAB;
243
244 /* Start clock if not running */
245 if (!clk_active_state) {
246 regmap_update_bits(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG,
247 BCM2835_CLK_PASSWD_MASK | BCM2835_CLK_ENAB,
248 BCM2835_CLK_PASSWD | BCM2835_CLK_ENAB);
249 }
250
251 /* Stop I2S module */
252 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, off, 0);
253
254 /*
255 * Clear the FIFOs
256 * Requires at least 2 PCM clock cycles to take effect
257 */
258 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, clr, clr);
259
260 /* Wait for 2 PCM clock cycles */
261
262 /*
263 * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back
264 * FIXME: This does not seem to work for slave mode!
265 */
266 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &syncval);
267 syncval &= BCM2835_I2S_SYNC;
268
269 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
270 BCM2835_I2S_SYNC, ~syncval);
271
272 /* Wait for the SYNC flag changing it's state */
273 while (--timeout) {
274 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg);
275 if ((csreg & BCM2835_I2S_SYNC) != syncval)
276 break;
277 }
278
279 if (!timeout)
280 dev_err(dev->dev, "I2S SYNC error!\n");
281
282 /* Stop clock if it was not running before */
283 if (!clk_active_state)
284 bcm2835_i2s_stop_clock(dev);
285
286 /* Restore I2S state */
287 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
288 BCM2835_I2S_RXON | BCM2835_I2S_TXON, i2s_active_state);
289}
290
291static int bcm2835_i2s_set_dai_fmt(struct snd_soc_dai *dai,
292 unsigned int fmt)
293{
294 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
295 dev->fmt = fmt;
296 return 0;
297}
298
299static int bcm2835_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai,
300 unsigned int ratio)
301{
302 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
303 dev->bclk_ratio = ratio;
304 return 0;
305}
306
307static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream,
308 struct snd_pcm_hw_params *params,
309 struct snd_soc_dai *dai)
310{
311 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
312
313 unsigned int sampling_rate = params_rate(params);
314 unsigned int data_length, data_delay, bclk_ratio;
315 unsigned int ch1pos, ch2pos, mode, format;
316 unsigned int mash = BCM2835_CLK_MASH_1;
317 unsigned int divi, divf, target_frequency;
318 int clk_src = -1;
319 unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK;
320 bool bit_master = (master == SND_SOC_DAIFMT_CBS_CFS
321 || master == SND_SOC_DAIFMT_CBS_CFM);
322
323 bool frame_master = (master == SND_SOC_DAIFMT_CBS_CFS
324 || master == SND_SOC_DAIFMT_CBM_CFS);
325 uint32_t csreg;
326
327 /*
328 * If a stream is already enabled,
329 * the registers are already set properly.
330 */
331 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &csreg);
332
333 if (csreg & (BCM2835_I2S_TXON | BCM2835_I2S_RXON))
334 return 0;
335
336 /*
337 * Adjust the data length according to the format.
338 * We prefill the half frame length with an integer
339 * divider of 2400 as explained at the clock settings.
340 * Maybe it is overwritten there, if the Integer mode
341 * does not apply.
342 */
343 switch (params_format(params)) {
344 case SNDRV_PCM_FORMAT_S16_LE:
345 data_length = 16;
346 bclk_ratio = 40;
347 break;
348 case SNDRV_PCM_FORMAT_S32_LE:
349 data_length = 32;
350 bclk_ratio = 80;
351 break;
352 default:
353 return -EINVAL;
354 }
355
356 /* If bclk_ratio already set, use that one. */
357 if (dev->bclk_ratio)
358 bclk_ratio = dev->bclk_ratio;
359
360 /*
361 * Clock Settings
362 *
363 * The target frequency of the bit clock is
364 * sampling rate * frame length
365 *
366 * Integer mode:
367 * Sampling rates that are multiples of 8000 kHz
368 * can be driven by the oscillator of 19.2 MHz
369 * with an integer divider as long as the frame length
370 * is an integer divider of 19200000/8000=2400 as set up above.
371 * This is no longer possible if the sampling rate
372 * is too high (e.g. 192 kHz), because the oscillator is too slow.
373 *
374 * MASH mode:
375 * For all other sampling rates, it is not possible to
376 * have an integer divider. Approximate the clock
377 * with the MASH module that induces a slight frequency
378 * variance. To minimize that it is best to have the fastest
379 * clock here. That is PLLD with 500 MHz.
380 */
381 target_frequency = sampling_rate * bclk_ratio;
382 clk_src = BCM2835_CLK_SRC_OSC;
383 mash = BCM2835_CLK_MASH_0;
384
385 if (bcm2835_clk_freq[clk_src] % target_frequency == 0
386 && bit_master && frame_master) {
387 divi = bcm2835_clk_freq[clk_src] / target_frequency;
388 divf = 0;
389 } else {
390 uint64_t dividend;
391
392 if (!dev->bclk_ratio) {
393 /*
394 * Overwrite bclk_ratio, because the
395 * above trick is not needed or can
396 * not be used.
397 */
398 bclk_ratio = 2 * data_length;
399 }
400
401 target_frequency = sampling_rate * bclk_ratio;
402
403 clk_src = BCM2835_CLK_SRC_PLLD;
404 mash = BCM2835_CLK_MASH_1;
405
406 dividend = bcm2835_clk_freq[clk_src];
407 dividend <<= BCM2835_CLK_SHIFT;
408 do_div(dividend, target_frequency);
409 divi = dividend >> BCM2835_CLK_SHIFT;
410 divf = dividend & BCM2835_CLK_DIVF_MASK;
411 }
412
413 /* Set clock divider */
414 regmap_write(dev->clk_regmap, BCM2835_CLK_PCMDIV_REG, BCM2835_CLK_PASSWD
415 | BCM2835_CLK_DIVI(divi)
416 | BCM2835_CLK_DIVF(divf));
417
418 /* Setup clock, but don't start it yet */
419 regmap_write(dev->clk_regmap, BCM2835_CLK_PCMCTL_REG, BCM2835_CLK_PASSWD
420 | BCM2835_CLK_MASH(mash)
421 | BCM2835_CLK_SRC(clk_src));
422
423 /* Setup the frame format */
424 format = BCM2835_I2S_CHEN;
425
426 if (data_length > 24)
427 format |= BCM2835_I2S_CHWEX;
428
429 format |= BCM2835_I2S_CHWID((data_length-8)&0xf);
430
431 switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
432 case SND_SOC_DAIFMT_I2S:
433 data_delay = 1;
434 break;
435 default:
436 /*
437 * TODO
438 * Others are possible but are not implemented at the moment.
439 */
440 dev_err(dev->dev, "%s:bad format\n", __func__);
441 return -EINVAL;
442 }
443
444 ch1pos = data_delay;
445 ch2pos = bclk_ratio / 2 + data_delay;
446
447 switch (params_channels(params)) {
448 case 2:
449 format = BCM2835_I2S_CH1(format) | BCM2835_I2S_CH2(format);
450 format |= BCM2835_I2S_CH1(BCM2835_I2S_CHPOS(ch1pos));
451 format |= BCM2835_I2S_CH2(BCM2835_I2S_CHPOS(ch2pos));
452 break;
453 default:
454 return -EINVAL;
455 }
456
457 /*
458 * Set format for both streams.
459 * We cannot set another frame length
460 * (and therefore word length) anyway,
461 * so the format will be the same.
462 */
463 regmap_write(dev->i2s_regmap, BCM2835_I2S_RXC_A_REG, format);
464 regmap_write(dev->i2s_regmap, BCM2835_I2S_TXC_A_REG, format);
465
466 /* Setup the I2S mode */
467 mode = 0;
468
469 if (data_length <= 16) {
470 /*
471 * Use frame packed mode (2 channels per 32 bit word)
472 * We cannot set another frame length in the second stream
473 * (and therefore word length) anyway,
474 * so the format will be the same.
475 */
476 mode |= BCM2835_I2S_FTXP | BCM2835_I2S_FRXP;
477 }
478
479 mode |= BCM2835_I2S_FLEN(bclk_ratio - 1);
480 mode |= BCM2835_I2S_FSLEN(bclk_ratio / 2);
481
482 /* Master or slave? */
483 switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
484 case SND_SOC_DAIFMT_CBS_CFS:
485 /* CPU is master */
486 break;
487 case SND_SOC_DAIFMT_CBM_CFS:
488 /*
489 * CODEC is bit clock master
490 * CPU is frame master
491 */
492 mode |= BCM2835_I2S_CLKM;
493 break;
494 case SND_SOC_DAIFMT_CBS_CFM:
495 /*
496 * CODEC is frame master
497 * CPU is bit clock master
498 */
499 mode |= BCM2835_I2S_FSM;
500 break;
501 case SND_SOC_DAIFMT_CBM_CFM:
502 /* CODEC is master */
503 mode |= BCM2835_I2S_CLKM;
504 mode |= BCM2835_I2S_FSM;
505 break;
506 default:
507 dev_err(dev->dev, "%s:bad master\n", __func__);
508 return -EINVAL;
509 }
510
511 /*
512 * Invert clocks?
513 *
514 * The BCM approach seems to be inverted to the classical I2S approach.
515 */
516 switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) {
517 case SND_SOC_DAIFMT_NB_NF:
518 /* None. Therefore, both for BCM */
519 mode |= BCM2835_I2S_CLKI;
520 mode |= BCM2835_I2S_FSI;
521 break;
522 case SND_SOC_DAIFMT_IB_IF:
523 /* Both. Therefore, none for BCM */
524 break;
525 case SND_SOC_DAIFMT_NB_IF:
526 /*
527 * Invert only frame sync. Therefore,
528 * invert only bit clock for BCM
529 */
530 mode |= BCM2835_I2S_CLKI;
531 break;
532 case SND_SOC_DAIFMT_IB_NF:
533 /*
534 * Invert only bit clock. Therefore,
535 * invert only frame sync for BCM
536 */
537 mode |= BCM2835_I2S_FSI;
538 break;
539 default:
540 return -EINVAL;
541 }
542
543 regmap_write(dev->i2s_regmap, BCM2835_I2S_MODE_A_REG, mode);
544
545 /* Setup the DMA parameters */
546 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
547 BCM2835_I2S_RXTHR(1)
548 | BCM2835_I2S_TXTHR(1)
549 | BCM2835_I2S_DMAEN, 0xffffffff);
550
551 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_DREQ_A_REG,
552 BCM2835_I2S_TX_PANIC(0x10)
553 | BCM2835_I2S_RX_PANIC(0x30)
554 | BCM2835_I2S_TX(0x30)
555 | BCM2835_I2S_RX(0x20), 0xffffffff);
556
557 /* Clear FIFOs */
558 bcm2835_i2s_clear_fifos(dev, true, true);
559
560 return 0;
561}
562
563static int bcm2835_i2s_prepare(struct snd_pcm_substream *substream,
564 struct snd_soc_dai *dai)
565{
566 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
567 uint32_t cs_reg;
568
569 bcm2835_i2s_start_clock(dev);
570
571 /*
572 * Clear both FIFOs if the one that should be started
573 * is not empty at the moment. This should only happen
574 * after overrun. Otherwise, hw_params would have cleared
575 * the FIFO.
576 */
577 regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &cs_reg);
578
579 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
580 && !(cs_reg & BCM2835_I2S_TXE))
581 bcm2835_i2s_clear_fifos(dev, true, false);
582 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE
583 && (cs_reg & BCM2835_I2S_RXD))
584 bcm2835_i2s_clear_fifos(dev, false, true);
585
586 return 0;
587}
588
589static void bcm2835_i2s_stop(struct bcm2835_i2s_dev *dev,
590 struct snd_pcm_substream *substream,
591 struct snd_soc_dai *dai)
592{
593 uint32_t mask;
594
595 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
596 mask = BCM2835_I2S_RXON;
597 else
598 mask = BCM2835_I2S_TXON;
599
600 regmap_update_bits(dev->i2s_regmap,
601 BCM2835_I2S_CS_A_REG, mask, 0);
602
603 /* Stop also the clock when not SND_SOC_DAIFMT_CONT */
604 if (!dai->active && !(dev->fmt & SND_SOC_DAIFMT_CONT))
605 bcm2835_i2s_stop_clock(dev);
606}
607
608static int bcm2835_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
609 struct snd_soc_dai *dai)
610{
611 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
612 uint32_t mask;
613
614 switch (cmd) {
615 case SNDRV_PCM_TRIGGER_START:
616 case SNDRV_PCM_TRIGGER_RESUME:
617 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
618 bcm2835_i2s_start_clock(dev);
619
620 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
621 mask = BCM2835_I2S_RXON;
622 else
623 mask = BCM2835_I2S_TXON;
624
625 regmap_update_bits(dev->i2s_regmap,
626 BCM2835_I2S_CS_A_REG, mask, mask);
627 break;
628
629 case SNDRV_PCM_TRIGGER_STOP:
630 case SNDRV_PCM_TRIGGER_SUSPEND:
631 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
632 bcm2835_i2s_stop(dev, substream, dai);
633 break;
634 default:
635 return -EINVAL;
636 }
637
638 return 0;
639}
640
641static int bcm2835_i2s_startup(struct snd_pcm_substream *substream,
642 struct snd_soc_dai *dai)
643{
644 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
645
646 if (dai->active)
647 return 0;
648
649 /* Should this still be running stop it */
650 bcm2835_i2s_stop_clock(dev);
651
652 /* Enable PCM block */
653 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
654 BCM2835_I2S_EN, BCM2835_I2S_EN);
655
656 /*
657 * Disable STBY.
658 * Requires at least 4 PCM clock cycles to take effect.
659 */
660 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
661 BCM2835_I2S_STBY, BCM2835_I2S_STBY);
662
663 return 0;
664}
665
666static void bcm2835_i2s_shutdown(struct snd_pcm_substream *substream,
667 struct snd_soc_dai *dai)
668{
669 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
670
671 bcm2835_i2s_stop(dev, substream, dai);
672
673 /* If both streams are stopped, disable module and clock */
674 if (dai->active)
675 return;
676
677 /* Disable the module */
678 regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG,
679 BCM2835_I2S_EN, 0);
680
681 /*
682 * Stopping clock is necessary, because stop does
683 * not stop the clock when SND_SOC_DAIFMT_CONT
684 */
685 bcm2835_i2s_stop_clock(dev);
686}
687
688static const struct snd_soc_dai_ops bcm2835_i2s_dai_ops = {
689 .startup = bcm2835_i2s_startup,
690 .shutdown = bcm2835_i2s_shutdown,
691 .prepare = bcm2835_i2s_prepare,
692 .trigger = bcm2835_i2s_trigger,
693 .hw_params = bcm2835_i2s_hw_params,
694 .set_fmt = bcm2835_i2s_set_dai_fmt,
695 .set_bclk_ratio = bcm2835_i2s_set_dai_bclk_ratio
696};
697
698static int bcm2835_i2s_dai_probe(struct snd_soc_dai *dai)
699{
700 struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
701
702 snd_soc_dai_init_dma_data(dai,
703 &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK],
704 &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]);
705
706 return 0;
707}
708
709static struct snd_soc_dai_driver bcm2835_i2s_dai = {
710 .name = "bcm2835-i2s",
711 .probe = bcm2835_i2s_dai_probe,
712 .playback = {
713 .channels_min = 2,
714 .channels_max = 2,
715 .rates = SNDRV_PCM_RATE_8000_192000,
716 .formats = SNDRV_PCM_FMTBIT_S16_LE
717 | SNDRV_PCM_FMTBIT_S32_LE
718 },
719 .capture = {
720 .channels_min = 2,
721 .channels_max = 2,
722 .rates = SNDRV_PCM_RATE_8000_192000,
723 .formats = SNDRV_PCM_FMTBIT_S16_LE
724 | SNDRV_PCM_FMTBIT_S32_LE
725 },
726 .ops = &bcm2835_i2s_dai_ops,
727 .symmetric_rates = 1
728};
729
730static bool bcm2835_i2s_volatile_reg(struct device *dev, unsigned int reg)
731{
732 switch (reg) {
733 case BCM2835_I2S_CS_A_REG:
734 case BCM2835_I2S_FIFO_A_REG:
735 case BCM2835_I2S_INTSTC_A_REG:
736 case BCM2835_I2S_GRAY_REG:
737 return true;
738 default:
739 return false;
740 };
741}
742
743static bool bcm2835_i2s_precious_reg(struct device *dev, unsigned int reg)
744{
745 switch (reg) {
746 case BCM2835_I2S_FIFO_A_REG:
747 return true;
748 default:
749 return false;
750 };
751}
752
753static bool bcm2835_clk_volatile_reg(struct device *dev, unsigned int reg)
754{
755 switch (reg) {
756 case BCM2835_CLK_PCMCTL_REG:
757 return true;
758 default:
759 return false;
760 };
761}
762
763static const struct regmap_config bcm2835_regmap_config[] = {
764 {
765 .reg_bits = 32,
766 .reg_stride = 4,
767 .val_bits = 32,
768 .max_register = BCM2835_I2S_GRAY_REG,
769 .precious_reg = bcm2835_i2s_precious_reg,
770 .volatile_reg = bcm2835_i2s_volatile_reg,
771 .cache_type = REGCACHE_RBTREE,
772 },
773 {
774 .reg_bits = 32,
775 .reg_stride = 4,
776 .val_bits = 32,
777 .max_register = BCM2835_CLK_PCMDIV_REG,
778 .volatile_reg = bcm2835_clk_volatile_reg,
779 .cache_type = REGCACHE_RBTREE,
780 },
781};
782
783static const struct snd_soc_component_driver bcm2835_i2s_component = {
784 .name = "bcm2835-i2s-comp",
785};
786
787static int bcm2835_i2s_probe(struct platform_device *pdev)
788{
789 struct bcm2835_i2s_dev *dev;
790 int i;
791 int ret;
792 struct regmap *regmap[2];
793 struct resource *mem[2];
794
795 /* Request both ioareas */
796 for (i = 0; i <= 1; i++) {
797 void __iomem *base;
798
799 mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i);
800 base = devm_ioremap_resource(&pdev->dev, mem[i]);
801 if (IS_ERR(base))
802 return PTR_ERR(base);
803
804 regmap[i] = devm_regmap_init_mmio(&pdev->dev, base,
805 &bcm2835_regmap_config[i]);
806 if (IS_ERR(regmap[i]))
807 return PTR_ERR(regmap[i]);
808 }
809
810 dev = devm_kzalloc(&pdev->dev, sizeof(*dev),
811 GFP_KERNEL);
812 if (!dev)
813 return -ENOMEM;
814
815 dev->i2s_regmap = regmap[0];
816 dev->clk_regmap = regmap[1];
817
818 /* Set the DMA address */
819 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr =
820 (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG
821 + BCM2835_VCMMU_SHIFT;
822
823 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr =
824 (dma_addr_t)mem[0]->start + BCM2835_I2S_FIFO_A_REG
825 + BCM2835_VCMMU_SHIFT;
826
827 /* Set the bus width */
828 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width =
829 DMA_SLAVE_BUSWIDTH_4_BYTES;
830 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width =
831 DMA_SLAVE_BUSWIDTH_4_BYTES;
832
833 /* Set burst */
834 dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2;
835 dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2;
836
837 /* BCLK ratio - use default */
838 dev->bclk_ratio = 0;
839
840 /* Store the pdev */
841 dev->dev = &pdev->dev;
842 dev_set_drvdata(&pdev->dev, dev);
843
844 ret = devm_snd_soc_register_component(&pdev->dev,
845 &bcm2835_i2s_component, &bcm2835_i2s_dai, 1);
846 if (ret) {
847 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
848 return ret;
849 }
850
851 ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
852 if (ret) {
853 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
854 return ret;
855 }
856
857 return 0;
858}
859
860static const struct of_device_id bcm2835_i2s_of_match[] = {
861 { .compatible = "brcm,bcm2835-i2s", },
862 {},
863};
864
865static int bcm2835_i2s_remove(struct platform_device *pdev)
866{
867 snd_dmaengine_pcm_unregister(&pdev->dev);
868 return 0;
869}
870
871static struct platform_driver bcm2835_i2s_driver = {
872 .probe = bcm2835_i2s_probe,
873 .remove = bcm2835_i2s_remove,
874 .driver = {
875 .name = "bcm2835-i2s",
876 .owner = THIS_MODULE,
877 .of_match_table = bcm2835_i2s_of_match,
878 },
879};
880
881module_platform_driver(bcm2835_i2s_driver);
882
883MODULE_ALIAS("platform:bcm2835-i2s");
884MODULE_DESCRIPTION("BCM2835 I2S interface");
885MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>");
886MODULE_LICENSE("GPL v2");