diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-08-15 16:16:15 +0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-08-15 16:16:15 +0200 |
commit | 1a10390708d675ebf1a2f5e169a5165626afbd88 (patch) | |
tree | d9ee7d10abd65e580fb74152a501089f51174225 /sound | |
parent | 239bd83104ec6bcba90221d8b0973d2565142ef8 (diff) | |
parent | b635acec48bcaa9183fcbf4e3955616b0d4119b5 (diff) |
Merge branch 'linus' into x86/cpu
Diffstat (limited to 'sound')
37 files changed, 291 insertions, 219 deletions
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 5b3274b465e..199cca3366d 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -26,10 +26,10 @@ #include <asm/irq.h> #include <linux/mutex.h> -#include <asm/hardware.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/pxa-regs.h> +#include <mach/pxa2xx-gpio.h> +#include <mach/audio.h> #include "pxa2xx-pcm.h" diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c index 0ede9e4656a..381094aab23 100644 --- a/sound/arm/pxa2xx-pcm.c +++ b/sound/arm/pxa2xx-pcm.c @@ -21,8 +21,8 @@ #include <sound/pcm_params.h> #include <asm/dma.h> -#include <asm/hardware.h> -#include <asm/arch/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/pxa-regs.h> #include "pxa2xx-pcm.h" diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c index faeddf3eced..b9c51bf8cd7 100644 --- a/sound/arm/sa11xx-uda1341.c +++ b/sound/arm/sa11xx-uda1341.c @@ -71,8 +71,8 @@ #include <linux/pm.h> #endif -#include <asm/hardware.h> -#include <asm/arch/h3600.h> +#include <mach/hardware.h> +#include <mach/h3600.h> #include <asm/mach-types.h> #include <asm/dma.h> diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index 558dadbf45f..e024e4588b8 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -604,6 +604,9 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in { struct seq_oss_synth *rec; + if (dev < 0 || dev >= dp->max_synthdev) + return -ENXIO; + if (dp->synths[dev].is_midi) { struct midi_info minf; snd_seq_oss_midi_make_info(dp, dp->synths[dev].midi_mapped, &minf); diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 87e3aefeddc..83e90057270 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -189,9 +189,7 @@ void snd_tea575x_init(struct snd_tea575x *tea) } memset(&tea->vd, 0, sizeof(tea->vd)); - tea->vd.owner = tea->card->module; strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio"); - tea->vd.type = VID_TYPE_TUNER; tea->vd.release = snd_tea575x_release; video_set_drvdata(&tea->vd, tea); tea->vd.fops = &tea->fops; diff --git a/sound/oss/vidc.c b/sound/oss/vidc.c index bb4a0969f46..725fef0f59a 100644 --- a/sound/oss/vidc.c +++ b/sound/oss/vidc.c @@ -22,7 +22,7 @@ #include <linux/kernel.h> #include <linux/interrupt.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/dma.h> #include <asm/io.h> #include <asm/hardware/iomd.h> diff --git a/sound/oss/vidc_fill.S b/sound/oss/vidc_fill.S index 01ccc074cc1..bed34921d17 100644 --- a/sound/oss/vidc_fill.S +++ b/sound/oss/vidc_fill.S @@ -11,7 +11,7 @@ */ #include <linux/linkage.h> #include <asm/assembler.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/hardware/iomd.h> .text diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c index 88490418f93..c47842fad65 100644 --- a/sound/oss/waveartist.c +++ b/sound/oss/waveartist.c @@ -47,7 +47,7 @@ #include "waveartist.h" #ifdef CONFIG_ARM -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/mach-types.h> #endif diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ef9f072b47f..a73d6ca0a90 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -101,6 +101,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{Intel, ICH8}," "{Intel, ICH9}," "{Intel, ICH10}," + "{Intel, PCH}," "{Intel, SCH}," "{ATI, SB450}," "{ATI, SB600}," @@ -2263,6 +2264,8 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x8086, 0x293f), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x3a3e), .driver_data = AZX_DRIVER_ICH }, { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH }, + /* PCH */ + { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH }, /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, /* ATI SB 450/600 */ @@ -2272,6 +2275,7 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x1002, 0x793b), .driver_data = AZX_DRIVER_ATIHDMI }, { PCI_DEVICE(0x1002, 0x7919), .driver_data = AZX_DRIVER_ATIHDMI }, { PCI_DEVICE(0x1002, 0x960f), .driver_data = AZX_DRIVER_ATIHDMI }, + { PCI_DEVICE(0x1002, 0x970f), .driver_data = AZX_DRIVER_ATIHDMI }, { PCI_DEVICE(0x1002, 0xaa00), .driver_data = AZX_DRIVER_ATIHDMI }, { PCI_DEVICE(0x1002, 0xaa08), .driver_data = AZX_DRIVER_ATIHDMI }, { PCI_DEVICE(0x1002, 0xaa10), .driver_data = AZX_DRIVER_ATIHDMI }, diff --git a/sound/sh/aica.c b/sound/sh/aica.c index 9ca11332614..54df8baf916 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c @@ -42,7 +42,7 @@ #include <sound/info.h> #include <asm/io.h> #include <asm/dma.h> -#include <asm/dreamcast/sysasic.h> +#include <mach/sysasic.h> #include "aica.h" MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>"); diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c index fee5f8e5895..3f326219f1e 100644 --- a/sound/soc/at32/playpaq_wm8510.c +++ b/sound/soc/at32/playpaq_wm8510.c @@ -36,8 +36,8 @@ #include <sound/soc.h> #include <sound/soc-dapm.h> -#include <asm/arch/at32ap700x.h> -#include <asm/arch/portmux.h> +#include <mach/at32ap700x.h> +#include <mach/portmux.h> #include "../codecs/wm8510.h" #include "at32-pcm.h" diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c index d47492b2b6e..7ab48bd25e4 100644 --- a/sound/soc/at91/at91-pcm.c +++ b/sound/soc/at91/at91-pcm.c @@ -28,8 +28,8 @@ #include <sound/pcm_params.h> #include <sound/soc.h> -#include <asm/arch/hardware.h> -#include <asm/arch/at91_ssc.h> +#include <mach/hardware.h> +#include <mach/at91_ssc.h> #include "at91-pcm.h" diff --git a/sound/soc/at91/at91-pcm.h b/sound/soc/at91/at91-pcm.h index 58d0f00a07b..e5aada2cb10 100644 --- a/sound/soc/at91/at91-pcm.h +++ b/sound/soc/at91/at91-pcm.h @@ -19,7 +19,7 @@ #ifndef _AT91_PCM_H #define _AT91_PCM_H -#include <asm/arch/hardware.h> +#include <mach/hardware.h> struct at91_ssc_periph { void __iomem *base; diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c index 090e607f869..5d44515e62e 100644 --- a/sound/soc/at91/at91-ssc.c +++ b/sound/soc/at91/at91-ssc.c @@ -28,9 +28,9 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <asm/arch/hardware.h> -#include <asm/arch/at91_pmc.h> -#include <asm/arch/at91_ssc.h> +#include <mach/hardware.h> +#include <mach/at91_pmc.h> +#include <mach/at91_ssc.h> #include "at91-pcm.h" #include "at91-ssc.h" diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c index d532de95424..b081e83766b 100644 --- a/sound/soc/at91/eti_b1_wm8731.c +++ b/sound/soc/at91/eti_b1_wm8731.c @@ -33,8 +33,8 @@ #include <sound/soc.h> #include <sound/soc-dapm.h> -#include <asm/hardware.h> -#include <asm/arch/gpio.h> +#include <mach/hardware.h> +#include <mach/gpio.h> #include "../codecs/wm8731.h" #include "at91-pcm.h" diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index e23cb09f0d1..c6a8edf302a 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -348,8 +348,9 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("ROUT1"), SND_SOC_DAPM_OUTPUT("LOUT2"), SND_SOC_DAPM_OUTPUT("ROUT2"), - SND_SOC_DAPM_OUTPUT("MONO"), + SND_SOC_DAPM_OUTPUT("MONO1"), SND_SOC_DAPM_OUTPUT("OUT3"), + SND_SOC_DAPM_OUTPUT("VREF"), SND_SOC_DAPM_INPUT("LINPUT1"), SND_SOC_DAPM_INPUT("LINPUT2"), diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 5e2c306399e..65fdbd81a37 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -19,9 +19,8 @@ #include <sound/soc.h> #include <sound/soc-dapm.h> -#include <asm/mach-types.h> #include <asm/dma.h> -#include <asm/arch/hardware.h> +#include <mach/hardware.h> #include "../codecs/tlv320aic3x.h" #include "davinci-pcm.h" diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index da2bc590286..d2d3da9729f 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -132,12 +132,17 @@ struct fsl_dma_private { * Since each link descriptor has a 32-bit byte count field, we set * period_bytes_max to the largest 32-bit number. We also have no maximum * number of periods. + * + * Note that we specify SNDRV_PCM_INFO_JOINT_DUPLEX here, but only because a + * limitation in the SSI driver requires the sample rates for playback and + * capture to be the same. */ static const struct snd_pcm_hardware fsl_dma_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID, + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_JOINT_DUPLEX, .formats = FSLDMA_PCM_FORMATS, .rates = FSLDMA_PCM_RATES, .rate_min = 5512, @@ -322,14 +327,75 @@ static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, * fsl_dma_open: open a new substream. * * Each substream has its own DMA buffer. + * + * ALSA divides the DMA buffer into N periods. We create NUM_DMA_LINKS link + * descriptors that ping-pong from one period to the next. For example, if + * there are six periods and two link descriptors, this is how they look + * before playback starts: + * + * The last link descriptor + * ____________ points back to the first + * | | + * V | + * ___ ___ | + * | |->| |->| + * |___| |___| + * | | + * | | + * V V + * _________________________________________ + * | | | | | | | The DMA buffer is + * | | | | | | | divided into 6 parts + * |______|______|______|______|______|______| + * + * and here's how they look after the first period is finished playing: + * + * ____________ + * | | + * V | + * ___ ___ | + * | |->| |->| + * |___| |___| + * | | + * |______________ + * | | + * V V + * _________________________________________ + * | | | | | | | + * | | | | | | | + * |______|______|______|______|______|______| + * + * The first link descriptor now points to the third period. The DMA + * controller is currently playing the second period. When it finishes, it + * will jump back to the first descriptor and play the third period. + * + * There are four reasons we do this: + * + * 1. The only way to get the DMA controller to automatically restart the + * transfer when it gets to the end of the buffer is to use chaining + * mode. Basic direct mode doesn't offer that feature. + * 2. We need to receive an interrupt at the end of every period. The DMA + * controller can generate an interrupt at the end of every link transfer + * (aka segment). Making each period into a DMA segment will give us the + * interrupts we need. + * 3. By creating only two link descriptors, regardless of the number of + * periods, we do not need to reallocate the link descriptors if the + * number of periods changes. + * 4. All of the audio data is still stored in a single, contiguous DMA + * buffer, which is what ALSA expects. We're just dividing it into + * contiguous parts, and creating a link descriptor for each one. */ static int fsl_dma_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct fsl_dma_private *dma_private; + struct ccsr_dma_channel __iomem *dma_channel; dma_addr_t ld_buf_phys; + u64 temp_link; /* Pointer to next link descriptor */ + u32 mr; unsigned int channel; int ret = 0; + unsigned int i; /* * Reject any DMA buffer whose size is not a multiple of the period @@ -390,68 +456,74 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware); runtime->private_data = dma_private; + /* Program the fixed DMA controller parameters */ + + dma_channel = dma_private->dma_channel; + + temp_link = dma_private->ld_buf_phys + + sizeof(struct fsl_dma_link_descriptor); + + for (i = 0; i < NUM_DMA_LINKS; i++) { + struct fsl_dma_link_descriptor *link = &dma_private->link[i]; + + link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); + link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); + link->next = cpu_to_be64(temp_link); + + temp_link += sizeof(struct fsl_dma_link_descriptor); + } + /* The last link descriptor points to the first */ + dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys); + + /* Tell the DMA controller where the first link descriptor is */ + out_be32(&dma_channel->clndar, + CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys)); + out_be32(&dma_channel->eclndar, + CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys)); + + /* The manual says the BCR must be clear before enabling EMP */ + out_be32(&dma_channel->bcr, 0); + + /* + * Program the mode register for interrupts, external master control, + * and source/destination hold. Also clear the Channel Abort bit. + */ + mr = in_be32(&dma_channel->mr) & + ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE); + + /* + * We want External Master Start and External Master Pause enabled, + * because the SSI is controlling the DMA controller. We want the DMA + * controller to be set up in advance, and then we signal only the SSI + * to start transferring. + * + * We want End-Of-Segment Interrupts enabled, because this will generate + * an interrupt at the end of each segment (each link descriptor + * represents one segment). Each DMA segment is the same thing as an + * ALSA period, so this is how we get an interrupt at the end of every + * period. + * + * We want Error Interrupt enabled, so that we can get an error if + * the DMA controller is mis-programmed somehow. + */ + mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN | + CCSR_DMA_MR_EMS_EN; + + /* For playback, we want the destination address to be held. For + capture, set the source address to be held. */ + mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE; + + out_be32(&dma_channel->mr, mr); + return 0; } /** - * fsl_dma_hw_params: allocate the DMA buffer and the DMA link descriptors. + * fsl_dma_hw_params: continue initializing the DMA links * - * ALSA divides the DMA buffer into N periods. We create NUM_DMA_LINKS link - * descriptors that ping-pong from one period to the next. For example, if - * there are six periods and two link descriptors, this is how they look - * before playback starts: - * - * The last link descriptor - * ____________ points back to the first - * | | - * V | - * ___ ___ | - * | |->| |->| - * |___| |___| - * | | - * | | - * V V - * _________________________________________ - * | | | | | | | The DMA buffer is - * | | | | | | | divided into 6 parts - * |______|______|______|______|______|______| - * - * and here's how they look after the first period is finished playing: - * - * ____________ - * | | - * V | - * ___ ___ | - * | |->| |->| - * |___| |___| - * | | - * |______________ - * | | - * V V - * _________________________________________ - * | | | | | | | - * | | | | | | | - * |______|______|______|______|______|______| - * - * The first link descriptor now points to the third period. The DMA - * controller is currently playing the second period. When it finishes, it - * will jump back to the first descriptor and play the third period. - * - * There are four reasons we do this: - * - * 1. The only way to get the DMA controller to automatically restart the - * transfer when it gets to the end of the buffer is to use chaining - * mode. Basic direct mode doesn't offer that feature. - * 2. We need to receive an interrupt at the end of every period. The DMA - * controller can generate an interrupt at the end of every link transfer - * (aka segment). Making each period into a DMA segment will give us the - * interrupts we need. - * 3. By creating only two link descriptors, regardless of the number of - * periods, we do not need to reallocate the link descriptors if the - * number of periods changes. - * 4. All of the audio data is still stored in a single, contiguous DMA - * buffer, which is what ALSA expects. We're just dividing it into - * contiguous parts, and creating a link descriptor for each one. + * This function obtains hardware parameters about the opened stream and + * programs the DMA controller accordingly. * * Note that due to a quirk of the SSI's STX register, the target address * for the DMA operations depends on the sample size. So we don't program @@ -463,11 +535,8 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, { struct snd_pcm_runtime *runtime = substream->runtime; struct fsl_dma_private *dma_private = runtime->private_data; - struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; dma_addr_t temp_addr; /* Pointer to next period */ - u64 temp_link; /* Pointer to next link descriptor */ - u32 mr; /* Temporary variable for MR register */ unsigned int i; @@ -485,8 +554,6 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, dma_private->dma_buf_next = dma_private->dma_buf_phys; /* - * Initialize each link descriptor. - * * The actual address in STX0 (destination for playback, source for * capture) is based on the sample size, but we don't know the sample * size in this function, so we'll have to adjust that later. See @@ -502,16 +569,11 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, * buffer itself. */ temp_addr = substream->dma_buffer.addr; - temp_link = dma_private->ld_buf_phys + - sizeof(struct fsl_dma_link_descriptor); for (i = 0; i < NUM_DMA_LINKS; i++) { struct fsl_dma_link_descriptor *link = &dma_private->link[i]; link->count = cpu_to_be32(period_size); - link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); - link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); - link->next = cpu_to_be64(temp_link); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) link->source_addr = cpu_to_be32(temp_addr); @@ -519,51 +581,7 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, link->dest_addr = cpu_to_be32(temp_addr); temp_addr += period_size; - temp_link += sizeof(struct fsl_dma_link_descriptor); } - /* The last link descriptor points to the first */ - dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys); - - /* Tell the DMA controller where the first link descriptor is */ - out_be32(&dma_channel->clndar, - CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys)); - out_be32(&dma_channel->eclndar, - CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys)); - - /* The manual says the BCR must be clear before enabling EMP */ - out_be32(&dma_channel->bcr, 0); - - /* - * Program the mode register for interrupts, external master control, - * and source/destination hold. Also clear the Channel Abort bit. - */ - mr = in_be32(&dma_channel->mr) & - ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE); - - /* - * We want External Master Start and External Master Pause enabled, - * because the SSI is controlling the DMA controller. We want the DMA - * controller to be set up in advance, and then we signal only the SSI - * to start transfering. - * - * We want End-Of-Segment Interrupts enabled, because this will generate - * an interrupt at the end of each segment (each link descriptor - * represents one segment). Each DMA segment is the same thing as an - * ALSA period, so this is how we get an interrupt at the end of every - * period. - * - * We want Error Interrupt enabled, so that we can get an error if - * the DMA controller is mis-programmed somehow. - */ - mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN | - CCSR_DMA_MR_EMS_EN; - - /* For playback, we want the destination address to be held. For - capture, set the source address to be held. */ - mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE; - - out_be32(&dma_channel->mr, mr); return 0; } diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 71bff33f552..157a7895ffa 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -67,6 +67,8 @@ * @ssi: pointer to the SSI's registers * @ssi_phys: physical address of the SSI registers * @irq: IRQ of this SSI + * @first_stream: pointer to the stream that was opened first + * @second_stream: pointer to second stream * @dev: struct device pointer * @playback: the number of playback streams opened * @capture: the number of capture streams opened @@ -79,6 +81,8 @@ struct fsl_ssi_private { struct ccsr_ssi __iomem *ssi; dma_addr_t ssi_phys; unsigned int irq; + struct snd_pcm_substream *first_stream; + struct snd_pcm_substream *second_stream; struct device *dev; unsigned int playback; unsigned int capture; @@ -342,6 +346,49 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream) */ } + if (!ssi_private->first_stream) + ssi_private->first_stream = substream; + else { + /* This is the second stream open, so we need to impose sample + * rate and maybe sample size constraints. Note that this can + * cause a race condition if the second stream is opened before + * the first stream is fully initialized. + * + * We provide some protection by checking to make sure the first + * stream is initialized, but it's not perfect. ALSA sometimes + * re-initializes the driver with a different sample rate or + * size. If the second stream is opened before the first stream + * has received its final parameters, then the second stream may + * be constrained to the wrong sample rate or size. + * + * FIXME: This code does not handle opening and closing streams + * repeatedly. If you open two streams and then close the first + * one, you may not be able to open another stream until you + * close the second one as well. + */ + struct snd_pcm_runtime *first_runtime = + ssi_private->first_stream->runtime; + + if (!first_runtime->rate || !first_runtime->sample_bits) { + dev_err(substream->pcm->card->dev, + "set sample rate and size in %s stream first\n", + substream->stream == SNDRV_PCM_STREAM_PLAYBACK + ? "capture" : "playback"); + return -EAGAIN; + } + + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, + first_runtime->rate, first_runtime->rate); + + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_SAMPLE_BITS, + first_runtime->sample_bits, + first_runtime->sample_bits); + + ssi_private->second_stream = substream; + } + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ssi_private->playback++; @@ -371,18 +418,16 @@ static int fsl_ssi_prepare(struct snd_pcm_substream *substream) struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; struct ccsr_ssi __iomem *ssi = ssi_private->ssi; - u32 wl; - wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format)); + if (substream == ssi_private->first_stream) { + u32 wl; - clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); + /* The SSI should always be disabled at this points (SSIEN=0) */ + wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format)); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + /* In synchronous mode, the SSI uses STCCR for capture */ clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); - else - clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); - - setbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); + } return 0; } @@ -407,9 +452,13 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - setbits32(&ssi->scr, CCSR_SSI_SCR_TE); + clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); + setbits32(&ssi->scr, + CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE); } else { - setbits32(&ssi->scr, CCSR_SSI_SCR_RE); + clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); + setbits32(&ssi->scr, + CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); /* * 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) if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ssi_private->capture--; + if (ssi_private->first_stream == substream) + ssi_private->first_stream = ssi_private->second_stream; + + ssi_private->second_stream = NULL; + /* * If this is the last active substream, disable the SSI and release * the IRQ. diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 02cec96859b..7694621ec40 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -29,9 +29,9 @@ #include <sound/soc-dapm.h> #include <asm/mach-types.h> -#include <asm/arch/hardware.h> +#include <mach/hardware.h> #include <linux/gpio.h> -#include <asm/arch/mcbsp.h> +#include <mach/mcbsp.h> #include "omap-mcbsp.h" #include "omap-pcm.h" diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 00b0c9d73cd..35310e16d7f 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -30,9 +30,9 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <asm/arch/control.h> -#include <asm/arch/dma.h> -#include <asm/arch/mcbsp.h> +#include <mach/control.h> +#include <mach/dma.h> +#include <mach/mcbsp.h> #include "omap-mcbsp.h" #include "omap-pcm.h" diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index e092f3d836d..690bfeaec4a 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -27,7 +27,7 @@ #include <sound/pcm_params.h> #include <sound/soc.h> -#include <asm/arch/dma.h> +#include <mach/dma.h> #include "omap-pcm.h" static const struct snd_pcm_hardware omap_pcm_hardware = { diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index c0294464a23..0a53f72077f 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -25,10 +25,10 @@ #include <asm/mach-types.h> #include <asm/hardware/scoop.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/corgi.h> -#include <asm/arch/audio.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/corgi.h> +#include <mach/audio.h> #include "../codecs/wm8731.h" #include "pxa2xx-pcm.h" diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index 06e8afb2527..6781c5be242 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c @@ -21,9 +21,9 @@ #include <sound/soc-dapm.h> #include <asm/mach-types.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/audio.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/audio.h> #include "../codecs/wm9712.h" #include "pxa2xx-pcm.h" diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c index 02dcac39cdf..d9c3f7b28be 100644 --- a/sound/soc/pxa/em-x270.c +++ b/sound/soc/pxa/em-x270.c @@ -30,9 +30,9 @@ #include <sound/soc-dapm.h> #include <asm/mach-types.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/audio.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/audio.h> #include "../codecs/wm9712.h" #include "pxa2xx-pcm.h" diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 65a4e9a8c39..a4697f7e292 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -26,10 +26,10 @@ #include <asm/mach-types.h> #include <asm/hardware/locomo.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/poodle.h> -#include <asm/arch/audio.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/poodle.h> +#include <mach/audio.h> #include "../codecs/wm8731.h" #include "pxa2xx-pcm.h" @@ -85,17 +85,13 @@ static int poodle_startup(struct snd_pcm_substream *substream) } /* we need to unmute the HP at shutdown as the mute burns power on poodle */ -static int poodle_shutdown(struct snd_pcm_substream *substream) +static void poodle_shutdown(struct snd_pcm_substream *substream) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->socdev->codec; - /* set = unmute headphone */ locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_L, 1); locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_R, 1); - return 0; } static int poodle_hw_params(struct snd_pcm_substream *substream, @@ -232,7 +228,7 @@ static const struct soc_enum poodle_enum[] = { SOC_ENUM_SINGLE_EXT(2, spk_function), }; -static const snd_kcontrol_new_t wm8731_poodle_controls[] = { +static const struct snd_kcontrol_new wm8731_poodle_controls[] = { SOC_ENUM_EXT("Jack Function", poodle_enum[0], poodle_get_jack, poodle_set_jack), SOC_ENUM_EXT("Speaker Function", poodle_enum[1], poodle_get_spk, diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 059af815ea0..d94a495bd6b 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -26,10 +26,10 @@ #include <asm/irq.h> #include <linux/mutex.h> -#include <asm/hardware.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/pxa-regs.h> +#include <mach/pxa2xx-gpio.h> +#include <mach/audio.h> #include "pxa2xx-pcm.h" #include "pxa2xx-ac97.h" diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 8f96d87f7b4..8548818eea0 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -21,10 +21,10 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <asm/hardware.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/pxa-regs.h> +#include <mach/pxa2xx-gpio.h> +#include <mach/audio.h> #include "pxa2xx-pcm.h" #include "pxa2xx-i2s.h" diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index 2df03ee5819..4345f387fe4 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c @@ -22,9 +22,9 @@ #include <sound/soc.h> #include <asm/dma.h> -#include <asm/hardware.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/pxa-regs.h> +#include <mach/audio.h> #include "pxa2xx-pcm.h" diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 64385797da5..37cb768fc93 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -26,10 +26,10 @@ #include <asm/mach-types.h> #include <asm/hardware/scoop.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/akita.h> -#include <asm/arch/spitz.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/akita.h> +#include <mach/spitz.h> #include "../codecs/wm8750.h" #include "pxa2xx-pcm.h" #include "pxa2xx-i2s.h" @@ -297,7 +297,7 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec) snd_soc_dapm_disable_pin(codec, "LINPUT3"); snd_soc_dapm_disable_pin(codec, "RINPUT3"); snd_soc_dapm_disable_pin(codec, "OUT3"); - snd_soc_dapm_disable_pin(codec, "MONO"); + snd_soc_dapm_disable_pin(codec, "MONO1"); /* Add spitz specific controls */ for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index fe6cca9c9e7..2baaa750f12 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -29,11 +29,10 @@ #include <sound/soc-dapm.h> #include <asm/mach-types.h> -#include <asm/arch/tosa.h> -#include <asm/arch/pxa-regs.h> -#include <asm/arch/hardware.h> -#include <asm/arch/audio.h> -#include <asm/arch/tosa.h> +#include <mach/tosa.h> +#include <mach/pxa-regs.h> +#include <mach/hardware.h> +#include <mach/audio.h> #include "../codecs/wm9712.h" #include "pxa2xx-pcm.h" diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index 4d7a9aa15f1..8089f8ee05c 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -24,14 +24,13 @@ #include <sound/soc-dapm.h> #include <sound/tlv.h> -#include <asm/mach-types.h> #include <asm/hardware/scoop.h> -#include <asm/arch/regs-clock.h> -#include <asm/arch/regs-gpio.h> -#include <asm/hardware.h> -#include <asm/arch/audio.h> +#include <mach/regs-clock.h> +#include <mach/regs-gpio.h> +#include <mach/hardware.h> +#include <mach/audio.h> #include <linux/io.h> -#include <asm/arch/spi-gpio.h> +#include <mach/spi-gpio.h> #include <asm/plat-s3c24xx/regs-iis.h> diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c index ee4676ed128..ded7d995a92 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/sound/soc/s3c24xx/s3c2412-i2s.c @@ -28,16 +28,16 @@ #include <sound/pcm_params.h> #include <sound/initval.h> #include <sound/soc.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <linux/io.h> #include <asm/dma.h> #include <asm/plat-s3c24xx/regs-s3c2412-iis.h> -#include <asm/arch/regs-gpio.h> -#include <asm/arch/audio.h> -#include <asm/arch/dma.h> +#include <mach/regs-gpio.h> +#include <mach/audio.h> +#include <mach/dma.h> #include "s3c24xx-pcm.h" #include "s3c2412-i2s.h" diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c index 783349b7fed..19c5c3cf5d8 100644 --- a/sound/soc/s3c24xx/s3c2443-ac97.c +++ b/sound/soc/s3c24xx/s3c2443-ac97.c @@ -27,13 +27,13 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <asm/hardware.h> +#include <mach/hardware.h> #include <asm/plat-s3c/regs-ac97.h> -#include <asm/arch/regs-gpio.h> -#include <asm/arch/regs-clock.h> -#include <asm/arch/audio.h> +#include <mach/regs-gpio.h> +#include <mach/regs-clock.h> +#include <mach/audio.h> #include <asm/dma.h> -#include <asm/arch/dma.h> +#include <mach/dma.h> #include "s3c24xx-pcm.h" #include "s3c24xx-ac97.h" diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index 397524282b5..ba4476b55fb 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -27,12 +27,12 @@ #include <sound/initval.h> #include <sound/soc.h> -#include <asm/hardware.h> -#include <asm/arch/regs-gpio.h> -#include <asm/arch/regs-clock.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/regs-gpio.h> +#include <mach/regs-clock.h> +#include <mach/audio.h> #include <asm/dma.h> -#include <asm/arch/dma.h> +#include <mach/dma.h> #include <asm/plat-s3c24xx/regs-iis.h> diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c index cef79b34dc6..e13e614bada 100644 --- a/sound/soc/s3c24xx/s3c24xx-pcm.c +++ b/sound/soc/s3c24xx/s3c24xx-pcm.c @@ -27,9 +27,9 @@ #include <sound/soc.h> #include <asm/dma.h> -#include <asm/hardware.h> -#include <asm/arch/dma.h> -#include <asm/arch/audio.h> +#include <mach/hardware.h> +#include <mach/dma.h> +#include <mach/audio.h> #include "s3c24xx-pcm.h" diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 820347c9ae4..f9d100bc847 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, return 0; } +EXPORT_SYMBOL_GPL(dapm_reg_event); /* * Scan each dapm widget for complete audio path. |