aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2012-03-16 04:56:42 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-04-01 06:28:27 -0400
commitdfa1a10785cf861c725aed0492f0ab69662bffea (patch)
treeb673bcb4ef40c1864c070e5f695796319e41d15e /sound/soc/fsl
parent8f549d7e7795e5e07ff871a79708bf2e387104dd (diff)
ASoC: fsl: make fsl_ssi driver compilable on ARM/IMX
Provide different pair of accessors for accessing SSI registers on PowerPC and ARM/IMX, so that fsl_ssi driver can be built on both architectures. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Acked-by: Sascha Hauer <s.hauer@pengutronix.de> Acked-by: Timur Tabi <timur@freescale.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/fsl_ssi.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 2eb407fa3b48..db9a73404385 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -11,11 +11,14 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/interrupt.h> 16#include <linux/interrupt.h>
16#include <linux/device.h> 17#include <linux/device.h>
17#include <linux/delay.h> 18#include <linux/delay.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/of_address.h>
21#include <linux/of_irq.h>
19#include <linux/of_platform.h> 22#include <linux/of_platform.h>
20 23
21#include <sound/core.h> 24#include <sound/core.h>
@@ -26,6 +29,25 @@
26 29
27#include "fsl_ssi.h" 30#include "fsl_ssi.h"
28 31
32#ifdef PPC
33#define read_ssi(addr) in_be32(addr)
34#define write_ssi(val, addr) out_be32(addr, val)
35#define write_ssi_mask(addr, clear, set) clrsetbits_be32(addr, clear, set)
36#elif defined ARM
37#define read_ssi(addr) readl(addr)
38#define write_ssi(val, addr) writel(val, addr)
39/*
40 * FIXME: Proper locking should be added at write_ssi_mask caller level
41 * to ensure this register read/modify/write sequence is race free.
42 */
43static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
44{
45 u32 val = readl(addr);
46 val = (val & ~clear) | set;
47 writel(val, addr);
48}
49#endif
50
29/** 51/**
30 * FSLSSI_I2S_RATES: sample rates supported by the I2S 52 * FSLSSI_I2S_RATES: sample rates supported by the I2S
31 * 53 *
@@ -145,7 +167,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
145 were interrupted for. We mask it with the Interrupt Enable register 167 were interrupted for. We mask it with the Interrupt Enable register
146 so that we only check for events that we're interested in. 168 so that we only check for events that we're interested in.
147 */ 169 */
148 sisr = in_be32(&ssi->sisr) & SIER_FLAGS; 170 sisr = read_ssi(&ssi->sisr) & SIER_FLAGS;
149 171
150 if (sisr & CCSR_SSI_SISR_RFRC) { 172 if (sisr & CCSR_SSI_SISR_RFRC) {
151 ssi_private->stats.rfrc++; 173 ssi_private->stats.rfrc++;
@@ -260,7 +282,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
260 282
261 /* Clear the bits that we set */ 283 /* Clear the bits that we set */
262 if (sisr2) 284 if (sisr2)
263 out_be32(&ssi->sisr, sisr2); 285 write_ssi(sisr2, &ssi->sisr);
264 286
265 return ret; 287 return ret;
266} 288}
@@ -295,7 +317,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
295 * SSI needs to be disabled before updating the registers we set 317 * SSI needs to be disabled before updating the registers we set
296 * here. 318 * here.
297 */ 319 */
298 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 320 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
299 321
300 /* 322 /*
301 * Program the SSI into I2S Slave Non-Network Synchronous mode. 323 * Program the SSI into I2S Slave Non-Network Synchronous mode.
@@ -303,20 +325,18 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
303 * 325 *
304 * FIXME: Little-endian samples require a different shift dir 326 * FIXME: Little-endian samples require a different shift dir
305 */ 327 */
306 clrsetbits_be32(&ssi->scr, 328 write_ssi_mask(&ssi->scr,
307 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, 329 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
308 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE 330 CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE
309 | (synchronous ? CCSR_SSI_SCR_SYN : 0)); 331 | (synchronous ? CCSR_SSI_SCR_SYN : 0));
310 332
311 out_be32(&ssi->stcr, 333 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
312 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 |
313 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS | 334 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS |
314 CCSR_SSI_STCR_TSCKP); 335 CCSR_SSI_STCR_TSCKP, &ssi->stcr);
315 336
316 out_be32(&ssi->srcr, 337 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
317 CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
318 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS | 338 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
319 CCSR_SSI_SRCR_RSCKP); 339 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
320 340
321 /* 341 /*
322 * The DC and PM bits are only used if the SSI is the clock 342 * The DC and PM bits are only used if the SSI is the clock
@@ -324,7 +344,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
324 */ 344 */
325 345
326 /* Enable the interrupts and DMA requests */ 346 /* Enable the interrupts and DMA requests */
327 out_be32(&ssi->sier, SIER_FLAGS); 347 write_ssi(SIER_FLAGS, &ssi->sier);
328 348
329 /* 349 /*
330 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We 350 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
@@ -339,9 +359,9 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
339 * make this value larger (and maybe we should), but this way 359 * make this value larger (and maybe we should), but this way
340 * data will be written to memory as soon as it's available. 360 * data will be written to memory as soon as it's available.
341 */ 361 */
342 out_be32(&ssi->sfcsr, 362 write_ssi(CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) |
343 CCSR_SSI_SFCSR_TFWM0(ssi_private->fifo_depth - 2) | 363 CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2),
344 CCSR_SSI_SFCSR_RFWM0(ssi_private->fifo_depth - 2)); 364 &ssi->sfcsr);
345 365
346 /* 366 /*
347 * We keep the SSI disabled because if we enable it, then the 367 * We keep the SSI disabled because if we enable it, then the
@@ -417,7 +437,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
417 unsigned int sample_size = 437 unsigned int sample_size =
418 snd_pcm_format_width(params_format(hw_params)); 438 snd_pcm_format_width(params_format(hw_params));
419 u32 wl = CCSR_SSI_SxCCR_WL(sample_size); 439 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
420 int enabled = in_be32(&ssi->scr) & CCSR_SSI_SCR_SSIEN; 440 int enabled = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
421 441
422 /* 442 /*
423 * If we're in synchronous mode, and the SSI is already enabled, 443 * If we're in synchronous mode, and the SSI is already enabled,
@@ -439,9 +459,9 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
439 /* In synchronous mode, the SSI uses STCCR for capture */ 459 /* In synchronous mode, the SSI uses STCCR for capture */
440 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || 460 if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
441 ssi_private->cpu_dai_drv.symmetric_rates) 461 ssi_private->cpu_dai_drv.symmetric_rates)
442 clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); 462 write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl);
443 else 463 else
444 clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); 464 write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
445 465
446 return 0; 466 return 0;
447} 467}
@@ -466,19 +486,19 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
466 case SNDRV_PCM_TRIGGER_START: 486 case SNDRV_PCM_TRIGGER_START:
467 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 487 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
468 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 488 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
469 setbits32(&ssi->scr, 489 write_ssi_mask(&ssi->scr, 0,
470 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); 490 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
471 else 491 else
472 setbits32(&ssi->scr, 492 write_ssi_mask(&ssi->scr, 0,
473 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); 493 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
474 break; 494 break;
475 495
476 case SNDRV_PCM_TRIGGER_STOP: 496 case SNDRV_PCM_TRIGGER_STOP:
477 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 497 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
478 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 498 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
479 clrbits32(&ssi->scr, CCSR_SSI_SCR_TE); 499 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0);
480 else 500 else
481 clrbits32(&ssi->scr, CCSR_SSI_SCR_RE); 501 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0);
482 break; 502 break;
483 503
484 default: 504 default:
@@ -510,7 +530,7 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
510 if (!ssi_private->first_stream) { 530 if (!ssi_private->first_stream) {
511 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 531 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
512 532
513 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 533 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
514 } 534 }
515} 535}
516 536