diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-01 14:44:24 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-01 14:44:24 -0400 |
| commit | df1efe6f871e2d3f83e6ad7b7a1d2b728b478fc2 (patch) | |
| tree | 1980e2df9bf8c5dbb1f562f09666451863662534 | |
| parent | 9a5467fd600669cda488771dac3e951034fe2b08 (diff) | |
| parent | 11589418a1c4cf68be9367f802898d35e07809c4 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
ALSA: ASoC: Export dapm_reg_event() fully
ALSA: ASoC: Update Poodle to current ASoC API
ALSA: asoc: restrict sample rate and size in Freescale MPC8610 sound drivers
ALSA: sound/soc/pxa/tosa.c: removed duplicated include
| -rw-r--r-- | include/sound/soc-dapm.h | 3 | ||||
| -rw-r--r-- | sound/soc/fsl/fsl_dma.c | 7 | ||||
| -rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 74 | ||||
| -rw-r--r-- | sound/soc/pxa/poodle.c | 8 | ||||
| -rw-r--r-- | sound/soc/pxa/tosa.c | 1 | ||||
| -rw-r--r-- | sound/soc/soc-dapm.c | 1 |
6 files changed, 76 insertions, 18 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 3030fdc6981d..c1b26fcc0b5c 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h | |||
| @@ -202,6 +202,9 @@ struct snd_soc_dapm_path; | |||
| 202 | struct snd_soc_dapm_pin; | 202 | struct snd_soc_dapm_pin; |
| 203 | struct snd_soc_dapm_route; | 203 | struct snd_soc_dapm_route; |
| 204 | 204 | ||
| 205 | int dapm_reg_event(struct snd_soc_dapm_widget *w, | ||
| 206 | struct snd_kcontrol *kcontrol, int event); | ||
| 207 | |||
| 205 | /* dapm controls */ | 208 | /* dapm controls */ |
| 206 | int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | 209 | int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, |
| 207 | struct snd_ctl_elem_value *ucontrol); | 210 | struct snd_ctl_elem_value *ucontrol); |
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index da2bc5902864..7ceea2bba1f5 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
| @@ -132,12 +132,17 @@ struct fsl_dma_private { | |||
| 132 | * Since each link descriptor has a 32-bit byte count field, we set | 132 | * Since each link descriptor has a 32-bit byte count field, we set |
| 133 | * period_bytes_max to the largest 32-bit number. We also have no maximum | 133 | * period_bytes_max to the largest 32-bit number. We also have no maximum |
| 134 | * number of periods. | 134 | * number of periods. |
| 135 | * | ||
| 136 | * Note that we specify SNDRV_PCM_INFO_JOINT_DUPLEX here, but only because a | ||
| 137 | * limitation in the SSI driver requires the sample rates for playback and | ||
| 138 | * capture to be the same. | ||
| 135 | */ | 139 | */ |
| 136 | static const struct snd_pcm_hardware fsl_dma_hardware = { | 140 | static const struct snd_pcm_hardware fsl_dma_hardware = { |
| 137 | 141 | ||
| 138 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 142 | .info = SNDRV_PCM_INFO_INTERLEAVED | |
| 139 | SNDRV_PCM_INFO_MMAP | | 143 | SNDRV_PCM_INFO_MMAP | |
| 140 | SNDRV_PCM_INFO_MMAP_VALID, | 144 | SNDRV_PCM_INFO_MMAP_VALID | |
| 145 | SNDRV_PCM_INFO_JOINT_DUPLEX, | ||
| 141 | .formats = FSLDMA_PCM_FORMATS, | 146 | .formats = FSLDMA_PCM_FORMATS, |
| 142 | .rates = FSLDMA_PCM_RATES, | 147 | .rates = FSLDMA_PCM_RATES, |
| 143 | .rate_min = 5512, | 148 | .rate_min = 5512, |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 71bff33f5528..157a7895ffa1 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
| @@ -67,6 +67,8 @@ | |||
| 67 | * @ssi: pointer to the SSI's registers | 67 | * @ssi: pointer to the SSI's registers |
| 68 | * @ssi_phys: physical address of the SSI registers | 68 | * @ssi_phys: physical address of the SSI registers |
| 69 | * @irq: IRQ of this SSI | 69 | * @irq: IRQ of this SSI |
| 70 | * @first_stream: pointer to the stream that was opened first | ||
| 71 | * @second_stream: pointer to second stream | ||
| 70 | * @dev: struct device pointer | 72 | * @dev: struct device pointer |
| 71 | * @playback: the number of playback streams opened | 73 | * @playback: the number of playback streams opened |
| 72 | * @capture: the number of capture streams opened | 74 | * @capture: the number of capture streams opened |
| @@ -79,6 +81,8 @@ struct fsl_ssi_private { | |||
| 79 | struct ccsr_ssi __iomem *ssi; | 81 | struct ccsr_ssi __iomem *ssi; |
| 80 | dma_addr_t ssi_phys; | 82 | dma_addr_t ssi_phys; |
| 81 | unsigned int irq; | 83 | unsigned int irq; |
| 84 | struct snd_pcm_substream *first_stream; | ||
| 85 | struct snd_pcm_substream *second_stream; | ||
| 82 | struct device *dev; | 86 | struct device *dev; |
| 83 | unsigned int playback; | 87 | unsigned int playback; |
| 84 | unsigned int capture; | 88 | unsigned int capture; |
| @@ -342,6 +346,49 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream) | |||
| 342 | */ | 346 | */ |
| 343 | } | 347 | } |
| 344 | 348 | ||
| 349 | if (!ssi_private->first_stream) | ||
| 350 | ssi_private->first_stream = substream; | ||
| 351 | else { | ||
| 352 | /* This is the second stream open, so we need to impose sample | ||
| 353 | * rate and maybe sample size constraints. Note that this can | ||
| 354 | * cause a race condition if the second stream is opened before | ||
| 355 | * the first stream is fully initialized. | ||
| 356 | * | ||
| 357 | * We provide some protection by checking to make sure the first | ||
| 358 | * stream is initialized, but it's not perfect. ALSA sometimes | ||
| 359 | * re-initializes the driver with a different sample rate or | ||
| 360 | * size. If the second stream is opened before the first stream | ||
| 361 | * has received its final parameters, then the second stream may | ||
| 362 | * be constrained to the wrong sample rate or size. | ||
| 363 | * | ||
| 364 | * FIXME: This code does not handle opening and closing streams | ||
| 365 | * repeatedly. If you open two streams and then close the first | ||
| 366 | * one, you may not be able to open another stream until you | ||
| 367 | * close the second one as well. | ||
| 368 | */ | ||
| 369 | struct snd_pcm_runtime *first_runtime = | ||
| 370 | ssi_private->first_stream->runtime; | ||
| 371 | |||
| 372 | if (!first_runtime->rate || !first_runtime->sample_bits) { | ||
| 373 | dev_err(substream->pcm->card->dev, | ||
| 374 | "set sample rate and size in %s stream first\n", | ||
| 375 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK | ||
| 376 | ? "capture" : "playback"); | ||
| 377 | return -EAGAIN; | ||
| 378 | } | ||
| 379 | |||
| 380 | snd_pcm_hw_constraint_minmax(substream->runtime, | ||
| 381 | SNDRV_PCM_HW_PARAM_RATE, | ||
| 382 | first_runtime->rate, first_runtime->rate); | ||
| 383 | |||
| 384 | snd_pcm_hw_constraint_minmax(substream->runtime, | ||
| 385 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, | ||
| 386 | first_runtime->sample_bits, | ||
| 387 | first_runtime->sample_bits); | ||
| 388 | |||
| 389 | ssi_private->second_stream = substream; | ||
| 390 | } | ||
| 391 | |||
| 345 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 392 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
| 346 | ssi_private->playback++; | 393 | ssi_private->playback++; |
| 347 | 394 | ||
| @@ -371,18 +418,16 @@ static int fsl_ssi_prepare(struct snd_pcm_substream *substream) | |||
| 371 | struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; | 418 | struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; |
| 372 | 419 | ||
| 373 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 420 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; |
| 374 | u32 wl; | ||
| 375 | 421 | ||
| 376 | wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format)); | 422 | if (substream == ssi_private->first_stream) { |
| 423 | u32 wl; | ||
| 377 | 424 | ||
| 378 | clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); | 425 | /* The SSI should always be disabled at this points (SSIEN=0) */ |
| 426 | wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format)); | ||
| 379 | 427 | ||
| 380 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 428 | /* In synchronous mode, the SSI uses STCCR for capture */ |
| 381 | clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); | 429 | clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); |
| 382 | else | 430 | } |
| 383 | clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); | ||
| 384 | |||
| 385 | setbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); | ||
| 386 | 431 | ||
| 387 | return 0; | 432 | return 0; |
| 388 | } | 433 | } |
| @@ -407,9 +452,13 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd) | |||
| 407 | case SNDRV_PCM_TRIGGER_RESUME: | 452 | case SNDRV_PCM_TRIGGER_RESUME: |
| 408 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 453 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 409 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 454 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 410 | setbits32(&ssi->scr, CCSR_SSI_SCR_TE); | 455 | clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); |
| 456 | setbits32(&ssi->scr, | ||
| 457 | CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); | ||
| 411 | } else { | 458 | } else { |
| 412 | setbits32(&ssi->scr, CCSR_SSI_SCR_RE); | 459 | clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); |
| 460 | setbits32(&ssi->scr, | ||
| 461 | CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); | ||
| 413 | 462 | ||
| 414 | /* | 463 | /* |
| 415 | * I think we need this delay to allow time for the SSI | 464 | * I think we need this delay to allow time for the SSI |
| @@ -452,6 +501,11 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream) | |||
| 452 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | 501 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
| 453 | ssi_private->capture--; | 502 | ssi_private->capture--; |
| 454 | 503 | ||
| 504 | if (ssi_private->first_stream == substream) | ||
| 505 | ssi_private->first_stream = ssi_private->second_stream; | ||
| 506 | |||
| 507 | ssi_private->second_stream = NULL; | ||
| 508 | |||
| 455 | /* | 509 | /* |
| 456 | * If this is the last active substream, disable the SSI and release | 510 | * If this is the last active substream, disable the SSI and release |
| 457 | * the IRQ. | 511 | * the IRQ. |
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 65a4e9a8c39e..d968cf71b569 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c | |||
| @@ -85,17 +85,13 @@ static int poodle_startup(struct snd_pcm_substream *substream) | |||
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | /* we need to unmute the HP at shutdown as the mute burns power on poodle */ | 87 | /* we need to unmute the HP at shutdown as the mute burns power on poodle */ |
| 88 | static int poodle_shutdown(struct snd_pcm_substream *substream) | 88 | static void poodle_shutdown(struct snd_pcm_substream *substream) |
| 89 | { | 89 | { |
| 90 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 91 | struct snd_soc_codec *codec = rtd->socdev->codec; | ||
| 92 | |||
| 93 | /* set = unmute headphone */ | 90 | /* set = unmute headphone */ |
| 94 | locomo_gpio_write(&poodle_locomo_device.dev, | 91 | locomo_gpio_write(&poodle_locomo_device.dev, |
| 95 | POODLE_LOCOMO_GPIO_MUTE_L, 1); | 92 | POODLE_LOCOMO_GPIO_MUTE_L, 1); |
| 96 | locomo_gpio_write(&poodle_locomo_device.dev, | 93 | locomo_gpio_write(&poodle_locomo_device.dev, |
| 97 | POODLE_LOCOMO_GPIO_MUTE_R, 1); | 94 | POODLE_LOCOMO_GPIO_MUTE_R, 1); |
| 98 | return 0; | ||
| 99 | } | 95 | } |
| 100 | 96 | ||
| 101 | static int poodle_hw_params(struct snd_pcm_substream *substream, | 97 | static int poodle_hw_params(struct snd_pcm_substream *substream, |
| @@ -232,7 +228,7 @@ static const struct soc_enum poodle_enum[] = { | |||
| 232 | SOC_ENUM_SINGLE_EXT(2, spk_function), | 228 | SOC_ENUM_SINGLE_EXT(2, spk_function), |
| 233 | }; | 229 | }; |
| 234 | 230 | ||
| 235 | static const snd_kcontrol_new_t wm8731_poodle_controls[] = { | 231 | static const struct snd_kcontrol_new wm8731_poodle_controls[] = { |
| 236 | SOC_ENUM_EXT("Jack Function", poodle_enum[0], poodle_get_jack, | 232 | SOC_ENUM_EXT("Jack Function", poodle_enum[0], poodle_get_jack, |
| 237 | poodle_set_jack), | 233 | poodle_set_jack), |
| 238 | SOC_ENUM_EXT("Speaker Function", poodle_enum[1], poodle_get_spk, | 234 | SOC_ENUM_EXT("Speaker Function", poodle_enum[1], poodle_get_spk, |
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index fe6cca9c9e76..22971a0f040e 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | #include <asm/arch/pxa-regs.h> | 33 | #include <asm/arch/pxa-regs.h> |
| 34 | #include <asm/arch/hardware.h> | 34 | #include <asm/arch/hardware.h> |
| 35 | #include <asm/arch/audio.h> | 35 | #include <asm/arch/audio.h> |
| 36 | #include <asm/arch/tosa.h> | ||
| 37 | 36 | ||
| 38 | #include "../codecs/wm9712.h" | 37 | #include "../codecs/wm9712.h" |
| 39 | #include "pxa2xx-pcm.h" | 38 | #include "pxa2xx-pcm.h" |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 820347c9ae4b..f9d100bc8479 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
| @@ -470,6 +470,7 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, | |||
| 470 | 470 | ||
| 471 | return 0; | 471 | return 0; |
| 472 | } | 472 | } |
| 473 | EXPORT_SYMBOL_GPL(dapm_reg_event); | ||
| 473 | 474 | ||
| 474 | /* | 475 | /* |
| 475 | * Scan each dapm widget for complete audio path. | 476 | * Scan each dapm widget for complete audio path. |
