aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/at91
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-11 15:58:37 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-11 15:58:37 -0400
commit0a3fd051c7036ef71b58863f8e5da7c3dabd9d3f (patch)
tree43388a81494ded94008afff66777f9f6e8cb5484 /sound/soc/at91
parent57a44415beee38d1afcd8e1b5fad66f3414d2dac (diff)
parentc911d1e16dfc1f0338bbc245ff724322c0113395 (diff)
Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
* 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: (122 commits) [ALSA] version 1.0.14rc4 [ALSA] Add speaker pin sequencing to hda_codec.c:snd_hda_parse_pin_def_config() [ALSA] hda-codec - Add ALC861VD Lenovo support [ALSA] hda-codec - Fix connection list in generic parser [ALSA] usb-audio: work around wrong wMaxPacketSize on ESI M4U [ALSA] usb-audio: work around broken M-Audio MidiSport Uno firmware [ALSA] usb-audio: explicitly match Logitech QuickCam [ALSA] hda-codec - Fix a typo [ALSA] hda-codec - Fix ALC880 uniwill auto-mutes [ALSA] hda-codec - Fix AD1988 SPDIF playback route control [ALSA] wm8750 typo fix [ALSA] wavefront: only declare isapnp on CONFIG_PNP [ALSA] hda-codec - bug fixes for stac92xx HDA codecs. [ALSA] add MODULE_FIRMWARE entries [ALSA] do not depend on FW_LOADER when internal firmware images are used [ALSA] hda-codec - Fix resume of STAC92xx codecs [ALSA] usbaudio - Revert the minimal period size fix patch [ALSA] hda-codec - Add support for new HP DV series laptops [ALSA] usb-audio - Fix the minimum period size per transfer mode [ALSA] sound/pcmcia/vx/vxpocket.c: fix an if() condition ...
Diffstat (limited to 'sound/soc/at91')
-rw-r--r--sound/soc/at91/Kconfig10
-rw-r--r--sound/soc/at91/Makefile4
-rw-r--r--sound/soc/at91/at91-ssc.c (renamed from sound/soc/at91/at91-i2s.c)259
-rw-r--r--sound/soc/at91/at91-ssc.h (renamed from sound/soc/at91/at91-i2s.h)14
-rw-r--r--sound/soc/at91/eti_b1_wm8731.c8
5 files changed, 181 insertions, 114 deletions
diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig
index a5b2558916c1..5cb93fd3a407 100644
--- a/sound/soc/at91/Kconfig
+++ b/sound/soc/at91/Kconfig
@@ -1,5 +1,3 @@
1menu "SoC Audio for the Atmel AT91"
2
3config SND_AT91_SOC 1config SND_AT91_SOC
4 tristate "SoC Audio for the Atmel AT91 System-on-Chip" 2 tristate "SoC Audio for the Atmel AT91 System-on-Chip"
5 depends on ARCH_AT91 && SND_SOC 3 depends on ARCH_AT91 && SND_SOC
@@ -8,13 +6,13 @@ config SND_AT91_SOC
8 the AT91 SSC interface. You will also need 6 the AT91 SSC interface. You will also need
9 to select the audio interfaces to support below. 7 to select the audio interfaces to support below.
10 8
11config SND_AT91_SOC_I2S 9config SND_AT91_SOC_SSC
12 tristate 10 tristate
13 11
14config SND_AT91_SOC_ETI_B1_WM8731 12config SND_AT91_SOC_ETI_B1_WM8731
15 tristate "SoC I2S Audio support for WM8731-based Endrelia ETI-B1 boards" 13 tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards"
16 depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1) 14 depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1)
17 select SND_AT91_SOC_I2S 15 select SND_AT91_SOC_SSC
18 select SND_SOC_WM8731 16 select SND_SOC_WM8731
19 help 17 help
20 Say Y if you want to add support for SoC audio on WM8731-based 18 Say Y if you want to add support for SoC audio on WM8731-based
@@ -27,5 +25,3 @@ config SND_AT91_SOC_ETI_SLAVE
27 help 25 help
28 Say Y if you want to run with the AT91 SSC generating the BCLK 26 Say Y if you want to run with the AT91 SSC generating the BCLK
29 and LRC signals on Endrelia boards. 27 and LRC signals on Endrelia boards.
30
31endmenu
diff --git a/sound/soc/at91/Makefile b/sound/soc/at91/Makefile
index b77b01ab2028..f23da17cc328 100644
--- a/sound/soc/at91/Makefile
+++ b/sound/soc/at91/Makefile
@@ -1,9 +1,9 @@
1# AT91 Platform Support 1# AT91 Platform Support
2snd-soc-at91-objs := at91-pcm.o 2snd-soc-at91-objs := at91-pcm.o
3snd-soc-at91-i2s-objs := at91-i2s.o 3snd-soc-at91-ssc-objs := at91-ssc.o
4 4
5obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o 5obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o
6obj-$(CONFIG_SND_AT91_SOC_I2S) += snd-soc-at91-i2s.o 6obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o
7 7
8# AT91 Machine Support 8# AT91 Machine Support
9snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o 9snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o
diff --git a/sound/soc/at91/at91-i2s.c b/sound/soc/at91/at91-ssc.c
index 9fc0c0388881..3d4e32cff75e 100644
--- a/sound/soc/at91/at91-i2s.c
+++ b/sound/soc/at91/at91-ssc.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * at91-i2s.c -- ALSA SoC I2S Audio Layer Platform driver 2 * at91-ssc.c -- ALSA SoC AT91 SSC Audio Layer Platform driver
3 * 3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com> 4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc. 5 * Endrelia Technologies Inc.
@@ -25,6 +25,7 @@
25#include <sound/driver.h> 25#include <sound/driver.h>
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/pcm.h> 27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
28#include <sound/initval.h> 29#include <sound/initval.h>
29#include <sound/soc.h> 30#include <sound/soc.h>
30 31
@@ -33,10 +34,10 @@
33#include <asm/arch/at91_ssc.h> 34#include <asm/arch/at91_ssc.h>
34 35
35#include "at91-pcm.h" 36#include "at91-pcm.h"
36#include "at91-i2s.h" 37#include "at91-ssc.h"
37 38
38#if 0 39#if 0
39#define DBG(x...) printk(KERN_DEBUG "at91-i2s:" x) 40#define DBG(x...) printk(KERN_DEBUG "at91-ssc:" x)
40#else 41#else
41#define DBG(x...) 42#define DBG(x...)
42#endif 43#endif
@@ -92,33 +93,33 @@ static struct at91_ssc_mask ssc_rx_mask = {
92 */ 93 */
93static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { 94static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
94 {{ 95 {{
95 .name = "SSC0/I2S PCM Stereo out", 96 .name = "SSC0 PCM out",
96 .pdc = &pdc_tx_reg, 97 .pdc = &pdc_tx_reg,
97 .mask = &ssc_tx_mask, 98 .mask = &ssc_tx_mask,
98 }, 99 },
99 { 100 {
100 .name = "SSC0/I2S PCM Stereo in", 101 .name = "SSC0 PCM in",
101 .pdc = &pdc_rx_reg, 102 .pdc = &pdc_rx_reg,
102 .mask = &ssc_rx_mask, 103 .mask = &ssc_rx_mask,
103 }}, 104 }},
104#if NUM_SSC_DEVICES == 3 105#if NUM_SSC_DEVICES == 3
105 {{ 106 {{
106 .name = "SSC1/I2S PCM Stereo out", 107 .name = "SSC1 PCM out",
107 .pdc = &pdc_tx_reg, 108 .pdc = &pdc_tx_reg,
108 .mask = &ssc_tx_mask, 109 .mask = &ssc_tx_mask,
109 }, 110 },
110 { 111 {
111 .name = "SSC1/I2S PCM Stereo in", 112 .name = "SSC1 PCM in",
112 .pdc = &pdc_rx_reg, 113 .pdc = &pdc_rx_reg,
113 .mask = &ssc_rx_mask, 114 .mask = &ssc_rx_mask,
114 }}, 115 }},
115 {{ 116 {{
116 .name = "SSC2/I2S PCM Stereo out", 117 .name = "SSC2 PCM out",
117 .pdc = &pdc_tx_reg, 118 .pdc = &pdc_tx_reg,
118 .mask = &ssc_tx_mask, 119 .mask = &ssc_tx_mask,
119 }, 120 },
120 { 121 {
121 .name = "SSC1/I2S PCM Stereo in", 122 .name = "SSC2 PCM in",
122 .pdc = &pdc_rx_reg, 123 .pdc = &pdc_rx_reg,
123 .mask = &ssc_rx_mask, 124 .mask = &ssc_rx_mask,
124 }}, 125 }},
@@ -151,33 +152,33 @@ static struct at91_ssc_info {
151} ssc_info[NUM_SSC_DEVICES] = { 152} ssc_info[NUM_SSC_DEVICES] = {
152 { 153 {
153 .name = "ssc0", 154 .name = "ssc0",
154 .lock = SPIN_LOCK_UNLOCKED, 155 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
155 .dir_mask = 0, 156 .dir_mask = 0,
156 .initialized = 0, 157 .initialized = 0,
157 }, 158 },
158#if NUM_SSC_DEVICES == 3 159#if NUM_SSC_DEVICES == 3
159 { 160 {
160 .name = "ssc1", 161 .name = "ssc1",
161 .lock = SPIN_LOCK_UNLOCKED, 162 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
162 .dir_mask = 0, 163 .dir_mask = 0,
163 .initialized = 0, 164 .initialized = 0,
164 }, 165 },
165 { 166 {
166 .name = "ssc2", 167 .name = "ssc2",
167 .lock = SPIN_LOCK_UNLOCKED, 168 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
168 .dir_mask = 0, 169 .dir_mask = 0,
169 .initialized = 0, 170 .initialized = 0,
170 }, 171 },
171#endif 172#endif
172}; 173};
173 174
174static unsigned int at91_i2s_sysclk; 175static unsigned int at91_ssc_sysclk;
175 176
176/* 177/*
177 * SSC interrupt handler. Passes PDC interrupts to the DMA 178 * SSC interrupt handler. Passes PDC interrupts to the DMA
178 * interrupt handler in the PCM driver. 179 * interrupt handler in the PCM driver.
179 */ 180 */
180static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id) 181static irqreturn_t at91_ssc_interrupt(int irq, void *dev_id)
181{ 182{
182 struct at91_ssc_info *ssc_p = dev_id; 183 struct at91_ssc_info *ssc_p = dev_id;
183 struct at91_pcm_dma_params *dma_params; 184 struct at91_pcm_dma_params *dma_params;
@@ -209,13 +210,13 @@ static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id)
209/* 210/*
210 * Startup. Only that one substream allowed in each direction. 211 * Startup. Only that one substream allowed in each direction.
211 */ 212 */
212static int at91_i2s_startup(struct snd_pcm_substream *substream) 213static int at91_ssc_startup(struct snd_pcm_substream *substream)
213{ 214{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 215 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; 216 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
216 int dir_mask; 217 int dir_mask;
217 218
218 DBG("i2s_startup: SSC_SR=0x%08lx\n", 219 DBG("ssc_startup: SSC_SR=0x%08lx\n",
219 at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)); 220 at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
220 dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2; 221 dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2;
221 222
@@ -234,7 +235,7 @@ static int at91_i2s_startup(struct snd_pcm_substream *substream)
234 * Shutdown. Clear DMA parameters and shutdown the SSC if there 235 * Shutdown. Clear DMA parameters and shutdown the SSC if there
235 * are no other substreams open. 236 * are no other substreams open.
236 */ 237 */
237static void at91_i2s_shutdown(struct snd_pcm_substream *substream) 238static void at91_ssc_shutdown(struct snd_pcm_substream *substream)
238{ 239{
239 struct snd_soc_pcm_runtime *rtd = substream->private_data; 240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
240 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; 241 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
@@ -281,7 +282,7 @@ static void at91_i2s_shutdown(struct snd_pcm_substream *substream)
281/* 282/*
282 * Record the SSC system clock rate. 283 * Record the SSC system clock rate.
283 */ 284 */
284static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, 285static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
285 int clk_id, unsigned int freq, int dir) 286 int clk_id, unsigned int freq, int dir)
286{ 287{
287 /* 288 /*
@@ -291,7 +292,7 @@ static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
291 */ 292 */
292 switch (clk_id) { 293 switch (clk_id) {
293 case AT91_SYSCLK_MCK: 294 case AT91_SYSCLK_MCK:
294 at91_i2s_sysclk = freq; 295 at91_ssc_sysclk = freq;
295 break; 296 break;
296 default: 297 default:
297 return -EINVAL; 298 return -EINVAL;
@@ -303,14 +304,11 @@ static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
303/* 304/*
304 * Record the DAI format for use in hw_params(). 305 * Record the DAI format for use in hw_params().
305 */ 306 */
306static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, 307static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
307 unsigned int fmt) 308 unsigned int fmt)
308{ 309{
309 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; 310 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
310 311
311 if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S)
312 return -EINVAL;
313
314 ssc_p->daifmt = fmt; 312 ssc_p->daifmt = fmt;
315 return 0; 313 return 0;
316} 314}
@@ -318,7 +316,7 @@ static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
318/* 316/*
319 * Record SSC clock dividers for use in hw_params(). 317 * Record SSC clock dividers for use in hw_params().
320 */ 318 */
321static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, 319static int at91_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
322 int div_id, int div) 320 int div_id, int div)
323{ 321{
324 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; 322 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
@@ -355,7 +353,7 @@ static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
355/* 353/*
356 * Configure the SSC. 354 * Configure the SSC.
357 */ 355 */
358static int at91_i2s_hw_params(struct snd_pcm_substream *substream, 356static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
359 struct snd_pcm_hw_params *params) 357 struct snd_pcm_hw_params *params)
360{ 358{
361 struct snd_soc_pcm_runtime *rtd = substream->private_data; 359 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -391,20 +389,50 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
391 channels = params_channels(params); 389 channels = params_channels(params);
392 390
393 /* 391 /*
392 * Determine sample size in bits and the PDC increment.
393 */
394 switch(params_format(params)) {
395 case SNDRV_PCM_FORMAT_S8:
396 bits = 8;
397 dma_params->pdc_xfer_size = 1;
398 break;
399 case SNDRV_PCM_FORMAT_S16_LE:
400 bits = 16;
401 dma_params->pdc_xfer_size = 2;
402 break;
403 case SNDRV_PCM_FORMAT_S24_LE:
404 bits = 24;
405 dma_params->pdc_xfer_size = 4;
406 break;
407 case SNDRV_PCM_FORMAT_S32_LE:
408 bits = 32;
409 dma_params->pdc_xfer_size = 4;
410 break;
411 default:
412 printk(KERN_WARNING "at91-ssc: unsupported PCM format");
413 return -EINVAL;
414 }
415
416 /*
394 * The SSC only supports up to 16-bit samples in I2S format, due 417 * The SSC only supports up to 16-bit samples in I2S format, due
395 * to the size of the Frame Mode Register FSLEN field. Also, I2S 418 * to the size of the Frame Mode Register FSLEN field.
396 * implies signed data.
397 */ 419 */
398 bits = 16; 420 if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
399 dma_params->pdc_xfer_size = 2; 421 && bits > 16) {
422 printk(KERN_WARNING
423 "at91-ssc: sample size %d is too large for I2S\n", bits);
424 return -EINVAL;
425 }
400 426
401 /* 427 /*
402 * Compute SSC register settings. 428 * Compute SSC register settings.
403 */ 429 */
404 switch (ssc_p->daifmt) { 430 switch (ssc_p->daifmt
405 case SND_SOC_DAIFMT_CBS_CFS: 431 & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
432
433 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
406 /* 434 /*
407 * SSC provides BCLK and LRC clocks. 435 * I2S format, SSC provides BCLK and LRC clocks.
408 * 436 *
409 * The SSC transmit and receive clocks are generated from the 437 * The SSC transmit and receive clocks are generated from the
410 * MCK divider, and the BCLK signal is output on the SSC TK line. 438 * MCK divider, and the BCLK signal is output on the SSC TK line.
@@ -441,10 +469,9 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
441 | (((bits - 1) << 0) & AT91_SSC_DATALEN); 469 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
442 break; 470 break;
443 471
444 case SND_SOC_DAIFMT_CBM_CFM: 472 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
445
446 /* 473 /*
447 * CODEC supplies BCLK and LRC clocks. 474 * I2S format, CODEC supplies BCLK and LRC clocks.
448 * 475 *
449 * The SSC transmit clock is obtained from the BCLK signal on 476 * The SSC transmit clock is obtained from the BCLK signal on
450 * on the TK line, and the SSC receive clock is generated from the 477 * on the TK line, and the SSC receive clock is generated from the
@@ -490,10 +517,51 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
490 | (((bits - 1) << 0) & AT91_SSC_DATALEN); 517 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
491 break; 518 break;
492 519
493 case SND_SOC_DAIFMT_CBS_CFM: 520 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
494 case SND_SOC_DAIFMT_CBM_CFS: 521 /*
522 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
523 *
524 * The SSC transmit and receive clocks are generated from the
525 * MCK divider, and the BCLK signal is output on the SSC TK line.
526 */
527 rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD)
528 | (( 1 << 16) & AT91_SSC_STTDLY)
529 | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START)
530 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
531 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
532 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
533
534 rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
535 | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS)
536 | (( 0 << 16) & AT91_SSC_FSLEN)
537 | (((channels - 1) << 8) & AT91_SSC_DATNB)
538 | (( 1 << 7) & AT91_SSC_MSBF)
539 | (( 0 << 5) & AT91_SSC_LOOP)
540 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
541
542 tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD)
543 | (( 1 << 16) & AT91_SSC_STTDLY)
544 | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START)
545 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
546 | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO)
547 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
548
549 tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
550 | (( 0 << 23) & AT91_SSC_FSDEN)
551 | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS)
552 | (( 0 << 16) & AT91_SSC_FSLEN)
553 | (((channels - 1) << 8) & AT91_SSC_DATNB)
554 | (( 1 << 7) & AT91_SSC_MSBF)
555 | (( 0 << 5) & AT91_SSC_DATDEF)
556 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
557
558
559
560 break;
561
562 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
495 default: 563 default:
496 printk(KERN_WARNING "at91-i2s: unsupported DAI format 0x%x.\n", 564 printk(KERN_WARNING "at91-ssc: unsupported DAI format 0x%x.\n",
497 ssc_p->daifmt); 565 ssc_p->daifmt);
498 return -EINVAL; 566 return -EINVAL;
499 break; 567 break;
@@ -518,9 +586,9 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
518 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0); 586 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0);
519 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0); 587 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0);
520 588
521 if ((ret = request_irq(ssc_p->ssc.pid, at91_i2s_interrupt, 589 if ((ret = request_irq(ssc_p->ssc.pid, at91_ssc_interrupt,
522 0, ssc_p->name, ssc_p)) < 0) { 590 0, ssc_p->name, ssc_p)) < 0) {
523 printk(KERN_WARNING "at91-i2s: request_irq failure\n"); 591 printk(KERN_WARNING "at91-ssc: request_irq failure\n");
524 592
525 DBG("Stopping pid %d clock\n", ssc_p->ssc.pid); 593 DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
526 at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid); 594 at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
@@ -546,7 +614,7 @@ static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
546} 614}
547 615
548 616
549static int at91_i2s_prepare(struct snd_pcm_substream *substream) 617static int at91_ssc_prepare(struct snd_pcm_substream *substream)
550{ 618{
551 struct snd_soc_pcm_runtime *rtd = substream->private_data; 619 struct snd_soc_pcm_runtime *rtd = substream->private_data;
552 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; 620 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
@@ -566,7 +634,7 @@ static int at91_i2s_prepare(struct snd_pcm_substream *substream)
566 634
567 635
568#ifdef CONFIG_PM 636#ifdef CONFIG_PM
569static int at91_i2s_suspend(struct platform_device *pdev, 637static int at91_ssc_suspend(struct platform_device *pdev,
570 struct snd_soc_cpu_dai *cpu_dai) 638 struct snd_soc_cpu_dai *cpu_dai)
571{ 639{
572 struct at91_ssc_info *ssc_p; 640 struct at91_ssc_info *ssc_p;
@@ -594,7 +662,7 @@ static int at91_i2s_suspend(struct platform_device *pdev,
594 return 0; 662 return 0;
595} 663}
596 664
597static int at91_i2s_resume(struct platform_device *pdev, 665static int at91_ssc_resume(struct platform_device *pdev,
598 struct snd_soc_cpu_dai *cpu_dai) 666 struct snd_soc_cpu_dai *cpu_dai)
599{ 667{
600 struct at91_ssc_info *ssc_p; 668 struct at91_ssc_info *ssc_p;
@@ -620,102 +688,105 @@ static int at91_i2s_resume(struct platform_device *pdev,
620} 688}
621 689
622#else 690#else
623#define at91_i2s_suspend NULL 691#define at91_ssc_suspend NULL
624#define at91_i2s_resume NULL 692#define at91_ssc_resume NULL
625#endif 693#endif
626 694
627#define AT91_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 695#define AT91_SSC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
628 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ 696 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
629 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ 697 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
630 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ 698 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
631 SNDRV_PCM_RATE_96000) 699 SNDRV_PCM_RATE_96000)
632 700
633struct snd_soc_cpu_dai at91_i2s_dai[NUM_SSC_DEVICES] = { 701#define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
634 { .name = "at91_ssc0/i2s", 702 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
703
704struct snd_soc_cpu_dai at91_ssc_dai[NUM_SSC_DEVICES] = {
705 { .name = "at91-ssc0",
635 .id = 0, 706 .id = 0,
636 .type = SND_SOC_DAI_I2S, 707 .type = SND_SOC_DAI_PCM,
637 .suspend = at91_i2s_suspend, 708 .suspend = at91_ssc_suspend,
638 .resume = at91_i2s_resume, 709 .resume = at91_ssc_resume,
639 .playback = { 710 .playback = {
640 .channels_min = 1, 711 .channels_min = 1,
641 .channels_max = 2, 712 .channels_max = 2,
642 .rates = AT91_I2S_RATES, 713 .rates = AT91_SSC_RATES,
643 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 714 .formats = AT91_SSC_FORMATS,},
644 .capture = { 715 .capture = {
645 .channels_min = 1, 716 .channels_min = 1,
646 .channels_max = 2, 717 .channels_max = 2,
647 .rates = AT91_I2S_RATES, 718 .rates = AT91_SSC_RATES,
648 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 719 .formats = AT91_SSC_FORMATS,},
649 .ops = { 720 .ops = {
650 .startup = at91_i2s_startup, 721 .startup = at91_ssc_startup,
651 .shutdown = at91_i2s_shutdown, 722 .shutdown = at91_ssc_shutdown,
652 .prepare = at91_i2s_prepare, 723 .prepare = at91_ssc_prepare,
653 .hw_params = at91_i2s_hw_params,}, 724 .hw_params = at91_ssc_hw_params,},
654 .dai_ops = { 725 .dai_ops = {
655 .set_sysclk = at91_i2s_set_dai_sysclk, 726 .set_sysclk = at91_ssc_set_dai_sysclk,
656 .set_fmt = at91_i2s_set_dai_fmt, 727 .set_fmt = at91_ssc_set_dai_fmt,
657 .set_clkdiv = at91_i2s_set_dai_clkdiv,}, 728 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
658 .private_data = &ssc_info[0].ssc, 729 .private_data = &ssc_info[0].ssc,
659 }, 730 },
660#if NUM_SSC_DEVICES == 3 731#if NUM_SSC_DEVICES == 3
661 { .name = "at91_ssc1/i2s", 732 { .name = "at91-ssc1",
662 .id = 1, 733 .id = 1,
663 .type = SND_SOC_DAI_I2S, 734 .type = SND_SOC_DAI_PCM,
664 .suspend = at91_i2s_suspend, 735 .suspend = at91_ssc_suspend,
665 .resume = at91_i2s_resume, 736 .resume = at91_ssc_resume,
666 .playback = { 737 .playback = {
667 .channels_min = 1, 738 .channels_min = 1,
668 .channels_max = 2, 739 .channels_max = 2,
669 .rates = AT91_I2S_RATES, 740 .rates = AT91_SSC_RATES,
670 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 741 .formats = AT91_SSC_FORMATS,},
671 .capture = { 742 .capture = {
672 .channels_min = 1, 743 .channels_min = 1,
673 .channels_max = 2, 744 .channels_max = 2,
674 .rates = AT91_I2S_RATES, 745 .rates = AT91_SSC_RATES,
675 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 746 .formats = AT91_SSC_FORMATS,},
676 .ops = { 747 .ops = {
677 .startup = at91_i2s_startup, 748 .startup = at91_ssc_startup,
678 .shutdown = at91_i2s_shutdown, 749 .shutdown = at91_ssc_shutdown,
679 .prepare = at91_i2s_prepare, 750 .prepare = at91_ssc_prepare,
680 .hw_params = at91_i2s_hw_params,}, 751 .hw_params = at91_ssc_hw_params,},
681 .dai_ops = { 752 .dai_ops = {
682 .set_sysclk = at91_i2s_set_dai_sysclk, 753 .set_sysclk = at91_ssc_set_dai_sysclk,
683 .set_fmt = at91_i2s_set_dai_fmt, 754 .set_fmt = at91_ssc_set_dai_fmt,
684 .set_clkdiv = at91_i2s_set_dai_clkdiv,}, 755 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
685 .private_data = &ssc_info[1].ssc, 756 .private_data = &ssc_info[1].ssc,
686 }, 757 },
687 { .name = "at91_ssc2/i2s", 758 { .name = "at91-ssc2",
688 .id = 2, 759 .id = 2,
689 .type = SND_SOC_DAI_I2S, 760 .type = SND_SOC_DAI_PCM,
690 .suspend = at91_i2s_suspend, 761 .suspend = at91_ssc_suspend,
691 .resume = at91_i2s_resume, 762 .resume = at91_ssc_resume,
692 .playback = { 763 .playback = {
693 .channels_min = 1, 764 .channels_min = 1,
694 .channels_max = 2, 765 .channels_max = 2,
695 .rates = AT91_I2S_RATES, 766 .rates = AT91_SSC_RATES,
696 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 767 .formats = AT91_SSC_FORMATS,},
697 .capture = { 768 .capture = {
698 .channels_min = 1, 769 .channels_min = 1,
699 .channels_max = 2, 770 .channels_max = 2,
700 .rates = AT91_I2S_RATES, 771 .rates = AT91_SSC_RATES,
701 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 772 .formats = AT91_SSC_FORMATS,},
702 .ops = { 773 .ops = {
703 .startup = at91_i2s_startup, 774 .startup = at91_ssc_startup,
704 .shutdown = at91_i2s_shutdown, 775 .shutdown = at91_ssc_shutdown,
705 .prepare = at91_i2s_prepare, 776 .prepare = at91_ssc_prepare,
706 .hw_params = at91_i2s_hw_params,}, 777 .hw_params = at91_ssc_hw_params,},
707 .dai_ops = { 778 .dai_ops = {
708 .set_sysclk = at91_i2s_set_dai_sysclk, 779 .set_sysclk = at91_ssc_set_dai_sysclk,
709 .set_fmt = at91_i2s_set_dai_fmt, 780 .set_fmt = at91_ssc_set_dai_fmt,
710 .set_clkdiv = at91_i2s_set_dai_clkdiv,}, 781 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
711 .private_data = &ssc_info[2].ssc, 782 .private_data = &ssc_info[2].ssc,
712 }, 783 },
713#endif 784#endif
714}; 785};
715 786
716EXPORT_SYMBOL_GPL(at91_i2s_dai); 787EXPORT_SYMBOL_GPL(at91_ssc_dai);
717 788
718/* Module information */ 789/* Module information */
719MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com"); 790MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
720MODULE_DESCRIPTION("AT91 I2S ASoC Interface"); 791MODULE_DESCRIPTION("AT91 SSC ASoC Interface");
721MODULE_LICENSE("GPL"); 792MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-i2s.h b/sound/soc/at91/at91-ssc.h
index f8a875ba0ccc..b188f973df9f 100644
--- a/sound/soc/at91/at91-i2s.h
+++ b/sound/soc/at91/at91-ssc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * at91-i2s.h - ALSA I2S interface for the Atmel AT91 SoC 2 * at91-ssc.h - ALSA SSC interface for the Atmel AT91 SoC
3 * 3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com> 4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc. 5 * Endrelia Technologies Inc.
@@ -10,18 +10,18 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#ifndef _AT91_I2S_H 13#ifndef _AT91_SSC_H
14#define _AT91_I2S_H 14#define _AT91_SSC_H
15 15
16/* I2S system clock ids */ 16/* SSC system clock ids */
17#define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */ 17#define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */
18 18
19/* I2S divider ids */ 19/* SSC divider ids */
20#define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */ 20#define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */
21#define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */ 21#define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
22#define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */ 22#define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
23 23
24extern struct snd_soc_cpu_dai at91_i2s_dai[]; 24extern struct snd_soc_cpu_dai at91_ssc_dai[];
25 25
26#endif /* _AT91_I2S_H */ 26#endif /* _AT91_SSC_H */
27 27
diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c
index 8179df3bb2f3..820a676c56bf 100644
--- a/sound/soc/at91/eti_b1_wm8731.c
+++ b/sound/soc/at91/eti_b1_wm8731.c
@@ -40,7 +40,7 @@
40 40
41#include "../codecs/wm8731.h" 41#include "../codecs/wm8731.h"
42#include "at91-pcm.h" 42#include "at91-pcm.h"
43#include "at91-i2s.h" 43#include "at91-ssc.h"
44 44
45#if 0 45#if 0
46#define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x) 46#define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x)
@@ -248,15 +248,15 @@ static int eti_b1_wm8731_init(struct snd_soc_codec *codec)
248 248
249static struct snd_soc_dai_link eti_b1_dai = { 249static struct snd_soc_dai_link eti_b1_dai = {
250 .name = "WM8731", 250 .name = "WM8731",
251 .stream_name = "WM8731", 251 .stream_name = "WM8731 PCM",
252 .cpu_dai = &at91_i2s_dai[1], 252 .cpu_dai = &at91_ssc_dai[1],
253 .codec_dai = &wm8731_dai, 253 .codec_dai = &wm8731_dai,
254 .init = eti_b1_wm8731_init, 254 .init = eti_b1_wm8731_init,
255 .ops = &eti_b1_ops, 255 .ops = &eti_b1_ops,
256}; 256};
257 257
258static struct snd_soc_machine snd_soc_machine_eti_b1 = { 258static struct snd_soc_machine snd_soc_machine_eti_b1 = {
259 .name = "ETI_B1", 259 .name = "ETI_B1_WM8731",
260 .dai_link = &eti_b1_dai, 260 .dai_link = &eti_b1_dai,
261 .num_links = 1, 261 .num_links = 1,
262}; 262};