diff options
Diffstat (limited to 'sound')
274 files changed, 1799 insertions, 940 deletions
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index 84bb07d39a7f..91852e49910e 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -33,6 +33,7 @@ */ #include <linux/delay.h> #include <linux/module.h> +#include <linux/slab.h> MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa"); diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index 1dd66ddffcaf..fd2188c3df2b 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c @@ -66,6 +66,7 @@ #include <linux/delay.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/slab.h> MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); MODULE_LICENSE("GPL"); diff --git a/sound/aoa/codecs/toonie.c b/sound/aoa/codecs/toonie.c index f13827e17562..69d2cb601f2a 100644 --- a/sound/aoa/codecs/toonie.c +++ b/sound/aoa/codecs/toonie.c @@ -11,6 +11,7 @@ */ #include <linux/delay.h> #include <linux/module.h> +#include <linux/slab.h> MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("toonie codec driver for snd-aoa"); diff --git a/sound/aoa/core/gpio-pmf.c b/sound/aoa/core/gpio-pmf.c index 1dd0c28d1fb7..6776d1c12b63 100644 --- a/sound/aoa/core/gpio-pmf.c +++ b/sound/aoa/core/gpio-pmf.c @@ -6,6 +6,7 @@ * GPL v2, can be found in COPYING. */ +#include <linux/slab.h> #include <asm/pmac_feature.h> #include <asm/pmac_pfunc.h> #include "../aoa.h" diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c index 7a437da05646..1cd9b301df03 100644 --- a/sound/aoa/fabrics/layout.c +++ b/sound/aoa/fabrics/layout.c @@ -12,6 +12,7 @@ #include <asm/prom.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/slab.h> #include "../aoa.h" #include "../soundbus/soundbus.h" diff --git a/sound/aoa/soundbus/i2sbus/control.c b/sound/aoa/soundbus/i2sbus/control.c index 87beb4ad4d63..47f854c2001f 100644 --- a/sound/aoa/soundbus/i2sbus/control.c +++ b/sound/aoa/soundbus/i2sbus/control.c @@ -8,6 +8,7 @@ #include <linux/kernel.h> #include <linux/delay.h> +#include <linux/slab.h> #include <asm/io.h> #include <asm/prom.h> diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index 4e3b819d4993..9d6f3b176ed1 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c @@ -7,6 +7,7 @@ */ #include <linux/module.h> +#include <linux/slab.h> #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/dma-mapping.h> diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c index 59bacd365733..be838993926d 100644 --- a/sound/aoa/soundbus/i2sbus/pcm.c +++ b/sound/aoa/soundbus/i2sbus/pcm.c @@ -8,6 +8,7 @@ #include <asm/io.h> #include <linux/delay.h> +#include <linux/slab.h> #include <sound/core.h> #include <asm/macio.h> #include <linux/pci.h> diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 656e474dca47..91acc9a243ec 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -863,7 +863,6 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci) struct snd_ac97 *ac97; int ret; - writel(0, aaci->base + AC97_POWERDOWN); /* * Assert AACIRESET for 2us */ @@ -1047,7 +1046,11 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id) writel(0x1fff, aaci->base + AACI_INTCLR); writel(aaci->maincr, aaci->base + AACI_MAINCR); - + /* + * Fix: ac97 read back fail errors by reading + * from any arbitrary aaci register. + */ + readl(aaci->base + AACI_CSCH1); ret = aaci_probe_ac97(aaci); if (ret) goto out; diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c index 6fdca97186e7..88eec3847df2 100644 --- a/sound/arm/pxa2xx-ac97-lib.c +++ b/sound/arm/pxa2xx-ac97-lib.c @@ -22,7 +22,6 @@ #include <asm/irq.h> #include <mach/regs-ac97.h> -#include <mach/pxa2xx-gpio.h> #include <mach/audio.h> static DEFINE_MUTEX(car_mutex); @@ -32,6 +31,8 @@ static struct clk *ac97_clk; static struct clk *ac97conf_clk; static int reset_gpio; +extern void pxa27x_assert_ac97reset(int reset_gpio, int on); + /* * Beware PXA27x bugs: * @@ -42,45 +43,6 @@ static int reset_gpio; * 1 jiffy timeout if interrupt never comes). */ -enum { - RESETGPIO_FORCE_HIGH, - RESETGPIO_FORCE_LOW, - RESETGPIO_NORMAL_ALTFUNC -}; - -/** - * set_resetgpio_mode - computes and sets the AC97_RESET gpio mode on PXA - * @mode: chosen action - * - * As the PXA27x CPUs suffer from a AC97 bug, a manual control of the reset line - * must be done to insure proper work of AC97 reset line. This function - * computes the correct gpio_mode for further use by reset functions, and - * applied the change through pxa_gpio_mode. - */ -static void set_resetgpio_mode(int resetgpio_action) -{ - int mode = 0; - - if (reset_gpio) - switch (resetgpio_action) { - case RESETGPIO_NORMAL_ALTFUNC: - if (reset_gpio == 113) - mode = 113 | GPIO_ALT_FN_2_OUT; - if (reset_gpio == 95) - mode = 95 | GPIO_ALT_FN_1_OUT; - break; - case RESETGPIO_FORCE_LOW: - mode = reset_gpio | GPIO_OUT | GPIO_DFLT_LOW; - break; - case RESETGPIO_FORCE_HIGH: - mode = reset_gpio | GPIO_OUT | GPIO_DFLT_HIGH; - break; - }; - - if (mode) - pxa_gpio_mode(mode); -} - unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg) { unsigned short val = -1; @@ -174,12 +136,11 @@ static inline void pxa_ac97_warm_pxa27x(void) { gsr_bits = 0; - /* warm reset broken on Bulverde, - so manually keep AC97 reset high */ - set_resetgpio_mode(RESETGPIO_FORCE_HIGH); + /* warm reset broken on Bulverde, so manually keep AC97 reset high */ + pxa27x_assert_ac97reset(reset_gpio, 1); udelay(10); GCR |= GCR_WARM_RST; - set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); + pxa27x_assert_ac97reset(reset_gpio, 0); udelay(500); } @@ -345,16 +306,6 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend); int pxa2xx_ac97_hw_resume(void) { - if (cpu_is_pxa25x() || cpu_is_pxa27x()) { - pxa_gpio_mode(GPIO31_SYNC_AC97_MD); - pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); - pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); - pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); - } - if (cpu_is_pxa27x()) { - /* Use GPIO 113 or 95 as AC97 Reset on Bulverde */ - set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); - } clk_enable(ac97_clk); return 0; } @@ -386,16 +337,9 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) reset_gpio = 113; } - if (cpu_is_pxa25x() || cpu_is_pxa27x()) { - pxa_gpio_mode(GPIO31_SYNC_AC97_MD); - pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); - pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); - pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); - } - if (cpu_is_pxa27x()) { /* Use GPIO 113 as AC97 Reset on Bulverde */ - set_resetgpio_mode(RESETGPIO_NORMAL_ALTFUNC); + pxa27x_assert_ac97reset(reset_gpio, 0); ac97conf_clk = clk_get(&dev->dev, "AC97CONFCLK"); if (IS_ERR(ac97conf_clk)) { ret = PTR_ERR(ac97conf_clk); diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c index 743ac6a29065..8808b82311b1 100644 --- a/sound/arm/pxa2xx-pcm-lib.c +++ b/sound/arm/pxa2xx-pcm-lib.c @@ -4,6 +4,7 @@ * published by the Free Software Foundation. */ +#include <linux/slab.h> #include <linux/module.h> #include <linux/dma-mapping.h> @@ -205,6 +206,7 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream) if (!rtd->dma_desc_array) goto err1; + rtd->dma_ch = -1; runtime->private_data = rtd; return 0; diff --git a/sound/atmel/Kconfig b/sound/atmel/Kconfig index 6c228a91940d..94de43a096f1 100644 --- a/sound/atmel/Kconfig +++ b/sound/atmel/Kconfig @@ -12,7 +12,7 @@ config SND_ATMEL_AC97C tristate "Atmel AC97 Controller (AC97C) driver" select SND_PCM select SND_AC97_CODEC - depends on DW_DMAC && AVR32 + depends on (DW_DMAC && AVR32) || ARCH_AT91 help ALSA sound driver for the Atmel AC97 controller. diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 0c0f8771656a..428121a7e705 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -13,6 +13,7 @@ #include <linux/device.h> #include <linux/dmaengine.h> #include <linux/dma-mapping.h> +#include <linux/atmel_pdc.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/module.h> @@ -31,6 +32,10 @@ #include <linux/dw_dmac.h> +#include <mach/cpu.h> +#include <mach/hardware.h> +#include <mach/gpio.h> + #include "ac97c.h" enum { @@ -63,6 +68,7 @@ struct atmel_ac97c { u64 cur_format; unsigned int cur_rate; unsigned long flags; + int playback_period, capture_period; /* Serialize access to opened variable */ spinlock_t lock; void __iomem *regs; @@ -242,10 +248,12 @@ static int atmel_ac97c_playback_hw_params(struct snd_pcm_substream *substream, if (retval < 0) return retval; /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ - if (retval == 1) - if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) - dw_dma_cyclic_free(chip->dma.tx_chan); - + if (cpu_is_at32ap7000()) { + /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ + if (retval == 1) + if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) + dw_dma_cyclic_free(chip->dma.tx_chan); + } /* Set restrictions to params. */ mutex_lock(&opened_mutex); chip->cur_rate = params_rate(hw_params); @@ -266,9 +274,14 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream, if (retval < 0) return retval; /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ - if (retval == 1) - if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) - dw_dma_cyclic_free(chip->dma.rx_chan); + if (cpu_is_at32ap7000()) { + if (retval < 0) + return retval; + /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ + if (retval == 1) + if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) + dw_dma_cyclic_free(chip->dma.rx_chan); + } /* Set restrictions to params. */ mutex_lock(&opened_mutex); @@ -282,16 +295,20 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream, static int atmel_ac97c_playback_hw_free(struct snd_pcm_substream *substream) { struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) - dw_dma_cyclic_free(chip->dma.tx_chan); + if (cpu_is_at32ap7000()) { + if (test_and_clear_bit(DMA_TX_READY, &chip->flags)) + dw_dma_cyclic_free(chip->dma.tx_chan); + } return snd_pcm_lib_free_pages(substream); } static int atmel_ac97c_capture_hw_free(struct snd_pcm_substream *substream) { struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) - dw_dma_cyclic_free(chip->dma.rx_chan); + if (cpu_is_at32ap7000()) { + if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) + dw_dma_cyclic_free(chip->dma.rx_chan); + } return snd_pcm_lib_free_pages(substream); } @@ -299,9 +316,11 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) { struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; + int block_size = frames_to_bytes(runtime, runtime->period_size); unsigned long word = ac97c_readl(chip, OCA); int retval; + chip->playback_period = 0; word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); /* assign channels to AC97C channel A */ @@ -320,11 +339,16 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) ac97c_writel(chip, OCA, word); /* configure sample format and size */ - word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; + word = ac97c_readl(chip, CAMR); + if (chip->opened <= 1) + word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; + else + word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; switch (runtime->format) { case SNDRV_PCM_FORMAT_S16_LE: - word |= AC97C_CMR_CEM_LITTLE; + if (cpu_is_at32ap7000()) + word |= AC97C_CMR_CEM_LITTLE; break; case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ word &= ~(AC97C_CMR_CEM_LITTLE); @@ -363,9 +387,18 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream) dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", runtime->rate); - if (!test_bit(DMA_TX_READY, &chip->flags)) - retval = atmel_ac97c_prepare_dma(chip, substream, - DMA_TO_DEVICE); + if (cpu_is_at32ap7000()) { + if (!test_bit(DMA_TX_READY, &chip->flags)) + retval = atmel_ac97c_prepare_dma(chip, substream, + DMA_TO_DEVICE); + } else { + /* Initialize and start the PDC */ + writel(runtime->dma_addr, chip->regs + ATMEL_PDC_TPR); + writel(block_size / 2, chip->regs + ATMEL_PDC_TCR); + writel(runtime->dma_addr + block_size, + chip->regs + ATMEL_PDC_TNPR); + writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR); + } return retval; } @@ -374,9 +407,11 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) { struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; + int block_size = frames_to_bytes(runtime, runtime->period_size); unsigned long word = ac97c_readl(chip, ICA); int retval; + chip->capture_period = 0; word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); /* assign channels to AC97C channel A */ @@ -395,11 +430,16 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) ac97c_writel(chip, ICA, word); /* configure sample format and size */ - word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; + word = ac97c_readl(chip, CAMR); + if (chip->opened <= 1) + word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; + else + word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; switch (runtime->format) { case SNDRV_PCM_FORMAT_S16_LE: - word |= AC97C_CMR_CEM_LITTLE; + if (cpu_is_at32ap7000()) + word |= AC97C_CMR_CEM_LITTLE; break; case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ word &= ~(AC97C_CMR_CEM_LITTLE); @@ -438,9 +478,18 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", runtime->rate); - if (!test_bit(DMA_RX_READY, &chip->flags)) - retval = atmel_ac97c_prepare_dma(chip, substream, - DMA_FROM_DEVICE); + if (cpu_is_at32ap7000()) { + if (!test_bit(DMA_RX_READY, &chip->flags)) + retval = atmel_ac97c_prepare_dma(chip, substream, + DMA_FROM_DEVICE); + } else { + /* Initialize and start the PDC */ + writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR); + writel(block_size / 2, chip->regs + ATMEL_PDC_RCR); + writel(runtime->dma_addr + block_size, + chip->regs + ATMEL_PDC_RNPR); + writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR); + } return retval; } @@ -449,7 +498,7 @@ static int atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) { struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - unsigned long camr; + unsigned long camr, ptcr = 0; int retval = 0; camr = ac97c_readl(chip, CAMR); @@ -458,15 +507,22 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ case SNDRV_PCM_TRIGGER_START: - retval = dw_dma_cyclic_start(chip->dma.tx_chan); - if (retval) - goto out; - camr |= AC97C_CMR_CENA; + if (cpu_is_at32ap7000()) { + retval = dw_dma_cyclic_start(chip->dma.tx_chan); + if (retval) + goto out; + } else { + ptcr = ATMEL_PDC_TXTEN; + } + camr |= AC97C_CMR_CENA | AC97C_CSR_ENDTX; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ case SNDRV_PCM_TRIGGER_STOP: - dw_dma_cyclic_stop(chip->dma.tx_chan); + if (cpu_is_at32ap7000()) + dw_dma_cyclic_stop(chip->dma.tx_chan); + else + ptcr |= ATMEL_PDC_TXTDIS; if (chip->opened <= 1) camr &= ~AC97C_CMR_CENA; break; @@ -476,6 +532,8 @@ atmel_ac97c_playback_trigger(struct snd_pcm_substream *substream, int cmd) } ac97c_writel(chip, CAMR, camr); + if (!cpu_is_at32ap7000()) + writel(ptcr, chip->regs + ATMEL_PDC_PTCR); out: return retval; } @@ -484,24 +542,32 @@ static int atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) { struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); - unsigned long camr; + unsigned long camr, ptcr = 0; int retval = 0; camr = ac97c_readl(chip, CAMR); + ptcr = readl(chip->regs + ATMEL_PDC_PTSR); switch (cmd) { case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ case SNDRV_PCM_TRIGGER_START: - retval = dw_dma_cyclic_start(chip->dma.rx_chan); - if (retval) - goto out; - camr |= AC97C_CMR_CENA; + if (cpu_is_at32ap7000()) { + retval = dw_dma_cyclic_start(chip->dma.rx_chan); + if (retval) + goto out; + } else { + ptcr = ATMEL_PDC_RXTEN; + } + camr |= AC97C_CMR_CENA | AC97C_CSR_ENDRX; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ case SNDRV_PCM_TRIGGER_STOP: - dw_dma_cyclic_stop(chip->dma.rx_chan); + if (cpu_is_at32ap7000()) + dw_dma_cyclic_stop(chip->dma.rx_chan); + else + ptcr |= (ATMEL_PDC_RXTDIS); if (chip->opened <= 1) camr &= ~AC97C_CMR_CENA; break; @@ -511,6 +577,8 @@ atmel_ac97c_capture_trigger(struct snd_pcm_substream *substream, int cmd) } ac97c_writel(chip, CAMR, camr); + if (!cpu_is_at32ap7000()) + writel(ptcr, chip->regs + ATMEL_PDC_PTCR); out: return retval; } @@ -523,7 +591,10 @@ atmel_ac97c_playback_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t frames; unsigned long bytes; - bytes = dw_dma_get_src_addr(chip->dma.tx_chan); + if (cpu_is_at32ap7000()) + bytes = dw_dma_get_src_addr(chip->dma.tx_chan); + else + bytes = readl(chip->regs + ATMEL_PDC_TPR); bytes -= runtime->dma_addr; frames = bytes_to_frames(runtime, bytes); @@ -540,7 +611,10 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t frames; unsigned long bytes; - bytes = dw_dma_get_dst_addr(chip->dma.rx_chan); + if (cpu_is_at32ap7000()) + bytes = dw_dma_get_dst_addr(chip->dma.rx_chan); + else + bytes = readl(chip->regs + ATMEL_PDC_RPR); bytes -= runtime->dma_addr; frames = bytes_to_frames(runtime, bytes); @@ -578,8 +652,11 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) u32 sr = ac97c_readl(chip, SR); u32 casr = ac97c_readl(chip, CASR); u32 cosr = ac97c_readl(chip, COSR); + u32 camr = ac97c_readl(chip, CAMR); if (sr & AC97C_SR_CAEVT) { + struct snd_pcm_runtime *runtime; + int offset, next_period, block_size; dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n", casr & AC97C_CSR_OVRUN ? " OVRUN" : "", casr & AC97C_CSR_RXRDY ? " RXRDY" : "", @@ -587,6 +664,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "", casr & AC97C_CSR_TXRDY ? " TXRDY" : "", !casr ? " NONE" : ""); + if (!cpu_is_at32ap7000()) { + if ((casr & camr) & AC97C_CSR_ENDTX) { + runtime = chip->playback_substream->runtime; + block_size = frames_to_bytes(runtime, + runtime->period_size); + chip->playback_period++; + + if (chip->playback_period == runtime->periods) + chip->playback_period = 0; + next_period = chip->playback_period + 1; + if (next_period == runtime->periods) + next_period = 0; + + offset = block_size * next_period; + + writel(runtime->dma_addr + offset, + chip->regs + ATMEL_PDC_TNPR); + writel(block_size / 2, + chip->regs + ATMEL_PDC_TNCR); + + snd_pcm_period_elapsed( + chip->playback_substream); + } + if ((casr & camr) & AC97C_CSR_ENDRX) { + runtime = chip->capture_substream->runtime; + block_size = frames_to_bytes(runtime, + runtime->period_size); + chip->capture_period++; + + if (chip->capture_period == runtime->periods) + chip->capture_period = 0; + next_period = chip->capture_period + 1; + if (next_period == runtime->periods) + next_period = 0; + + offset = block_size * next_period; + + writel(runtime->dma_addr + offset, + chip->regs + ATMEL_PDC_RNPR); + writel(block_size / 2, + chip->regs + ATMEL_PDC_RNCR); + snd_pcm_period_elapsed(chip->capture_substream); + } + } retval = IRQ_HANDLED; } @@ -608,15 +729,50 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) return retval; } +static struct ac97_pcm at91_ac97_pcm_defs[] __devinitdata = { + /* Playback */ + { + .exclusive = 1, + .r = { { + .slots = ((1 << AC97_SLOT_PCM_LEFT) + | (1 << AC97_SLOT_PCM_RIGHT)), + } }, + }, + /* PCM in */ + { + .stream = 1, + .exclusive = 1, + .r = { { + .slots = ((1 << AC97_SLOT_PCM_LEFT) + | (1 << AC97_SLOT_PCM_RIGHT)), + } } + }, + /* Mic in */ + { + .stream = 1, + .exclusive = 1, + .r = { { + .slots = (1<<AC97_SLOT_MIC), + } } + }, +}; + static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip) { struct snd_pcm *pcm; struct snd_pcm_hardware hw = atmel_ac97c_hw; - int capture, playback, retval; + int capture, playback, retval, err; capture = test_bit(DMA_RX_CHAN_PRESENT, &chip->flags); playback = test_bit(DMA_TX_CHAN_PRESENT, &chip->flags); + if (!cpu_is_at32ap7000()) { + err = snd_ac97_pcm_assign(chip->ac97_bus, + ARRAY_SIZE(at91_ac97_pcm_defs), + at91_ac97_pcm_defs); + if (err) + return err; + } retval = snd_pcm_new(chip->card, chip->card->shortname, chip->pdev->id, playback, capture, &pcm); if (retval) @@ -775,7 +931,12 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev) return -ENXIO; } - pclk = clk_get(&pdev->dev, "pclk"); + if (cpu_is_at32ap7000()) { + pclk = clk_get(&pdev->dev, "pclk"); + } else { + pclk = clk_get(&pdev->dev, "ac97_clk"); + } + if (IS_ERR(pclk)) { dev_dbg(&pdev->dev, "no peripheral clock\n"); return PTR_ERR(pclk); @@ -844,43 +1005,52 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev) goto err_ac97_bus; } - if (pdata->rx_dws.dma_dev) { - struct dw_dma_slave *dws = &pdata->rx_dws; - dma_cap_mask_t mask; + if (cpu_is_at32ap7000()) { + if (pdata->rx_dws.dma_dev) { + struct dw_dma_slave *dws = &pdata->rx_dws; + dma_cap_mask_t mask; - dws->rx_reg = regs->start + AC97C_CARHR + 2; + dws->rx_reg = regs->start + AC97C_CARHR + 2; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); - chip->dma.rx_chan = dma_request_channel(mask, filter, dws); + chip->dma.rx_chan = dma_request_channel(mask, filter, + dws); - dev_info(&chip->pdev->dev, "using %s for DMA RX\n", + dev_info(&chip->pdev->dev, "using %s for DMA RX\n", dev_name(&chip->dma.rx_chan->dev->device)); - set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); - } + set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); + } - if (pdata->tx_dws.dma_dev) { - struct dw_dma_slave *dws = &pdata->tx_dws; - dma_cap_mask_t mask; + if (pdata->tx_dws.dma_dev) { + struct dw_dma_slave *dws = &pdata->tx_dws; + dma_cap_mask_t mask; - dws->tx_reg = regs->start + AC97C_CATHR + 2; + dws->tx_reg = regs->start + AC97C_CATHR + 2; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); - chip->dma.tx_chan = dma_request_channel(mask, filter, dws); + chip->dma.tx_chan = dma_request_channel(mask, filter, + dws); - dev_info(&chip->pdev->dev, "using %s for DMA TX\n", + dev_info(&chip->pdev->dev, "using %s for DMA TX\n", dev_name(&chip->dma.tx_chan->dev->device)); - set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); - } + set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); + } - if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) && - !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) { - dev_dbg(&pdev->dev, "DMA not available\n"); - retval = -ENODEV; - goto err_dma; + if (!test_bit(DMA_RX_CHAN_PRESENT, &chip->flags) && + !test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) { + dev_dbg(&pdev->dev, "DMA not available\n"); + retval = -ENODEV; + goto err_dma; + } + } else { + /* Just pretend that we have DMA channel(for at91 i is actually + * the PDC) */ + set_bit(DMA_RX_CHAN_PRESENT, &chip->flags); + set_bit(DMA_TX_CHAN_PRESENT, &chip->flags); } retval = atmel_ac97c_pcm_new(chip); @@ -897,20 +1067,22 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, card); - dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p\n", - chip->regs); + dev_info(&pdev->dev, "Atmel AC97 controller at 0x%p, irq = %d\n", + chip->regs, irq); return 0; err_dma: - if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) - dma_release_channel(chip->dma.rx_chan); - if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) - dma_release_channel(chip->dma.tx_chan); - clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); - clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); - chip->dma.rx_chan = NULL; - chip->dma.tx_chan = NULL; + if (cpu_is_at32ap7000()) { + if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) + dma_release_channel(chip->dma.rx_chan); + if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) + dma_release_channel(chip->dma.tx_chan); + clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); + clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); + chip->dma.rx_chan = NULL; + chip->dma.tx_chan = NULL; + } err_ac97_bus: snd_card_set_dev(card, NULL); @@ -934,10 +1106,12 @@ static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg) struct snd_card *card = platform_get_drvdata(pdev); struct atmel_ac97c *chip = card->private_data; - if (test_bit(DMA_RX_READY, &chip->flags)) - dw_dma_cyclic_stop(chip->dma.rx_chan); - if (test_bit(DMA_TX_READY, &chip->flags)) - dw_dma_cyclic_stop(chip->dma.tx_chan); + if (cpu_is_at32ap7000()) { + if (test_bit(DMA_RX_READY, &chip->flags)) + dw_dma_cyclic_stop(chip->dma.rx_chan); + if (test_bit(DMA_TX_READY, &chip->flags)) + dw_dma_cyclic_stop(chip->dma.tx_chan); + } clk_disable(chip->pclk); return 0; @@ -949,11 +1123,12 @@ static int atmel_ac97c_resume(struct platform_device *pdev) struct atmel_ac97c *chip = card->private_data; clk_enable(chip->pclk); - if (test_bit(DMA_RX_READY, &chip->flags)) - dw_dma_cyclic_start(chip->dma.rx_chan); - if (test_bit(DMA_TX_READY, &chip->flags)) - dw_dma_cyclic_start(chip->dma.tx_chan); - + if (cpu_is_at32ap7000()) { + if (test_bit(DMA_RX_READY, &chip->flags)) + dw_dma_cyclic_start(chip->dma.rx_chan); + if (test_bit(DMA_TX_READY, &chip->flags)) + dw_dma_cyclic_start(chip->dma.tx_chan); + } return 0; } #else @@ -978,14 +1153,16 @@ static int __devexit atmel_ac97c_remove(struct platform_device *pdev) iounmap(chip->regs); free_irq(chip->irq, chip); - if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) - dma_release_channel(chip->dma.rx_chan); - if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) - dma_release_channel(chip->dma.tx_chan); - clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); - clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); - chip->dma.rx_chan = NULL; - chip->dma.tx_chan = NULL; + if (cpu_is_at32ap7000()) { + if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags)) + dma_release_channel(chip->dma.rx_chan); + if (test_bit(DMA_TX_CHAN_PRESENT, &chip->flags)) + dma_release_channel(chip->dma.tx_chan); + clear_bit(DMA_RX_CHAN_PRESENT, &chip->flags); + clear_bit(DMA_TX_CHAN_PRESENT, &chip->flags); + chip->dma.rx_chan = NULL; + chip->dma.tx_chan = NULL; + } snd_card_set_dev(card, NULL); snd_card_free(card); diff --git a/sound/core/control.c b/sound/core/control.c index 439ce64f9d82..070aab490191 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -50,6 +50,10 @@ static int snd_ctl_open(struct inode *inode, struct file *file) struct snd_ctl_file *ctl; int err; + err = nonseekable_open(inode, file); + if (err < 0) + return err; + card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL); if (!card) { err = -ENODEV; @@ -1388,6 +1392,7 @@ static const struct file_operations snd_ctl_f_ops = .read = snd_ctl_read, .open = snd_ctl_open, .release = snd_ctl_release, + .llseek = no_llseek, .poll = snd_ctl_poll, .unlocked_ioctl = snd_ctl_ioctl, .compat_ioctl = snd_ctl_ioctl_compat, diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index 368dc9c4aef8..426874429a5e 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c @@ -21,6 +21,7 @@ /* this file included from control.c */ #include <linux/compat.h> +#include <linux/slab.h> struct snd_ctl_elem_list32 { u32 offset; diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c index 7f4d744ae40a..7730575bfadd 100644 --- a/sound/core/hrtimer.c +++ b/sound/core/hrtimer.c @@ -19,6 +19,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/hrtimer.h> diff --git a/sound/core/info.c b/sound/core/info.c index d749a0d394a7..b70564ed8b37 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -22,6 +22,7 @@ #include <linux/init.h> #include <linux/time.h> #include <linux/mm.h> +#include <linux/slab.h> #include <linux/smp_lock.h> #include <linux/string.h> #include <sound/core.h> @@ -163,40 +164,44 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) { struct snd_info_private_data *data; struct snd_info_entry *entry; - loff_t ret; + loff_t ret = -EINVAL, size; data = file->private_data; entry = data->entry; - lock_kernel(); - switch (entry->content) { - case SNDRV_INFO_CONTENT_TEXT: - switch (orig) { - case SEEK_SET: - file->f_pos = offset; - ret = file->f_pos; - goto out; - case SEEK_CUR: - file->f_pos += offset; - ret = file->f_pos; - goto out; - case SEEK_END: - default: - ret = -EINVAL; - goto out; - } + mutex_lock(&entry->access); + if (entry->content == SNDRV_INFO_CONTENT_DATA && + entry->c.ops->llseek) { + offset = entry->c.ops->llseek(entry, + data->file_private_data, + file, offset, orig); + goto out; + } + if (entry->content == SNDRV_INFO_CONTENT_DATA) + size = entry->size; + else + size = 0; + switch (orig) { + case SEEK_SET: break; - case SNDRV_INFO_CONTENT_DATA: - if (entry->c.ops->llseek) { - ret = entry->c.ops->llseek(entry, - data->file_private_data, - file, offset, orig); + case SEEK_CUR: + offset += file->f_pos; + break; + case SEEK_END: + if (!size) goto out; - } + offset += size; break; - } - ret = -ENXIO; -out: - unlock_kernel(); + default: + goto out; + } + if (offset < 0) + goto out; + if (size && offset > size) + offset = size; + file->f_pos = offset; + ret = offset; + out: + mutex_unlock(&entry->access); return ret; } @@ -231,10 +236,15 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer, return -EFAULT; break; case SNDRV_INFO_CONTENT_DATA: - if (entry->c.ops->read) + if (pos >= entry->size) + return 0; + if (entry->c.ops->read) { + size = entry->size - pos; + size = min(count, size); size = entry->c.ops->read(entry, data->file_private_data, - file, buffer, count, pos); + file, buffer, size, pos); + } break; } if ((ssize_t) size > 0) @@ -281,10 +291,13 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer size = count; break; case SNDRV_INFO_CONTENT_DATA: - if (entry->c.ops->write) + if (entry->c.ops->write && count > 0) { + size_t maxsize = entry->size - pos; + count = min(count, maxsize); size = entry->c.ops->write(entry, data->file_private_data, file, buffer, count, pos); + } break; } if ((ssize_t) size > 0) diff --git a/sound/core/jack.c b/sound/core/jack.c index f705eec7372a..14b8a4ee690d 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -20,6 +20,7 @@ */ #include <linux/input.h> +#include <linux/slab.h> #include <sound/jack.h> #include <sound/core.h> diff --git a/sound/core/misc.c b/sound/core/misc.c index 3da4f92427d8..2c41825c836e 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/time.h> +#include <linux/slab.h> #include <linux/ioport.h> #include <sound/core.h> diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 54e2eb56e4c2..f50ebf20df96 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -43,6 +43,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) struct snd_mixer_oss_file *fmixer; int err; + err = nonseekable_open(inode, file); + if (err < 0) + return err; + card = snd_lookup_oss_minor_data(iminor(inode), SNDRV_OSS_DEVICE_TYPE_MIXER); if (card == NULL) @@ -397,6 +401,7 @@ static const struct file_operations snd_mixer_oss_f_ops = .owner = THIS_MODULE, .open = snd_mixer_oss_open, .release = snd_mixer_oss_release, + .llseek = no_llseek, .unlocked_ioctl = snd_mixer_oss_ioctl, .compat_ioctl = snd_mixer_oss_ioctl_compat, }; diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 82d4e3329b3d..5c8c7dff8ede 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -2379,6 +2379,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) int nonblock; wait_queue_t wait; + err = nonseekable_open(inode, file); + if (err < 0) + return err; + pcm = snd_lookup_oss_minor_data(iminor(inode), SNDRV_OSS_DEVICE_TYPE_PCM); if (pcm == NULL) { @@ -2977,6 +2981,7 @@ static const struct file_operations snd_pcm_oss_f_reg = .write = snd_pcm_oss_write, .open = snd_pcm_oss_open, .release = snd_pcm_oss_release, + .llseek = no_llseek, .poll = snd_pcm_oss_poll, .unlocked_ioctl = snd_pcm_oss_ioctl, .compat_ioctl = snd_pcm_oss_ioctl_compat, diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c index 0dcc2870d537..bbe25d8c450a 100644 --- a/sound/core/oss/route.c +++ b/sound/core/oss/route.c @@ -19,7 +19,6 @@ * */ -#include <linux/slab.h> #include <linux/time.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index 08bfed594a83..5fb2e28e796f 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c @@ -21,6 +21,7 @@ /* This file included from pcm_native.c */ #include <linux/compat.h> +#include <linux/slab.h> static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream, s32 __user *src) diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index b546ac2660f9..a2ff86189d2a 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -148,6 +148,9 @@ static void pcm_debug_name(struct snd_pcm_substream *substream, #define xrun_debug(substream, mask) \ ((substream)->pstr->xrun_debug & (mask)) +#else +#define xrun_debug(substream, mask) 0 +#endif #define dump_stack_on_xrun(substream) do { \ if (xrun_debug(substream, XRUN_DEBUG_STACK)) \ @@ -169,6 +172,7 @@ static void xrun(struct snd_pcm_substream *substream) } } +#ifdef CONFIG_SND_PCM_XRUN_DEBUG #define hw_ptr_error(substream, fmt, args...) \ do { \ if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ @@ -255,8 +259,6 @@ static void xrun_log_show(struct snd_pcm_substream *substream) #else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ -#define xrun_debug(substream, mask) 0 -#define xrun(substream) do { } while (0) #define hw_ptr_error(substream, fmt, args...) do { } while (0) #define xrun_log(substream, pos) do { } while (0) #define xrun_log_show(substream) do { } while (0) diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index d6d49d6651f9..917e4055ee30 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -22,6 +22,7 @@ #include <asm/io.h> #include <linux/time.h> #include <linux/init.h> +#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/vmalloc.h> #include <sound/core.h> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 9681518aa392..4c3edc1532c9 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -36,6 +36,9 @@ #include <sound/timer.h> #include <sound/minors.h> #include <asm/io.h> +#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) +#include <dma-coherence.h> +#endif /* * Compatibility @@ -2107,7 +2110,9 @@ static int snd_pcm_open_file(struct file *file, static int snd_pcm_playback_open(struct inode *inode, struct file *file) { struct snd_pcm *pcm; - + int err = nonseekable_open(inode, file); + if (err < 0) + return err; pcm = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_PCM_PLAYBACK); return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); @@ -2116,7 +2121,9 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file) static int snd_pcm_capture_open(struct inode *inode, struct file *file) { struct snd_pcm *pcm; - + int err = nonseekable_open(inode, file); + if (err < 0) + return err; pcm = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_PCM_CAPTURE); return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); @@ -3184,6 +3191,10 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, substream->runtime->dma_area, substream->runtime->dma_addr, area->vm_end - area->vm_start); +#elif defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT) + if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV && + !plat_device_is_coherent(substream->dma_buffer.dev.dev)) + area->vm_page_prot = pgprot_noncached(area->vm_page_prot); #endif /* ARCH_HAS_DMA_MMAP_COHERENT */ /* mmap with fault handler */ area->vm_ops = &snd_pcm_vm_ops_data_fault; @@ -3303,18 +3314,13 @@ static int snd_pcm_fasync(int fd, struct file * file, int on) struct snd_pcm_file * pcm_file; struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; - int err = -ENXIO; - lock_kernel(); pcm_file = file->private_data; substream = pcm_file->substream; if (PCM_RUNTIME_CHECK(substream)) - goto out; + return -ENXIO; runtime = substream->runtime; - err = fasync_helper(fd, file, on, &runtime->fasync); -out: - unlock_kernel(); - return err; + return fasync_helper(fd, file, on, &runtime->fasync); } /* @@ -3469,6 +3475,7 @@ const struct file_operations snd_pcm_f_ops[2] = { .aio_write = snd_pcm_aio_write, .open = snd_pcm_playback_open, .release = snd_pcm_release, + .llseek = no_llseek, .poll = snd_pcm_playback_poll, .unlocked_ioctl = snd_pcm_playback_ioctl, .compat_ioctl = snd_pcm_ioctl_compat, @@ -3482,6 +3489,7 @@ const struct file_operations snd_pcm_f_ops[2] = { .aio_read = snd_pcm_aio_read, .open = snd_pcm_capture_open, .release = snd_pcm_release, + .llseek = no_llseek, .poll = snd_pcm_capture_poll, .unlocked_ioctl = snd_pcm_capture_ioctl, .compat_ioctl = snd_pcm_ioctl_compat, diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 0f5a194695d9..eb68326c37d4 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -376,6 +376,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) return -EINVAL; /* invalid combination */ + err = nonseekable_open(inode, file); + if (err < 0) + return err; + if (maj == snd_major) { rmidi = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_RAWMIDI); @@ -1391,6 +1395,7 @@ static const struct file_operations snd_rawmidi_f_ops = .write = snd_rawmidi_write, .open = snd_rawmidi_open, .release = snd_rawmidi_release, + .llseek = no_llseek, .poll = snd_rawmidi_poll, .unlocked_ioctl = snd_rawmidi_ioctl, .compat_ioctl = snd_rawmidi_ioctl_compat, diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index d0d721c22eac..685712276ac9 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c @@ -29,6 +29,7 @@ #include "seq_oss_event.h" #include <linux/init.h> #include <linux/moduleparam.h> +#include <linux/slab.h> /* * common variables diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index 9dfb2f77be60..677dc84590c7 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c @@ -28,6 +28,7 @@ #include <sound/seq_midi_event.h> #include "../seq_lock.h" #include <linux/init.h> +#include <linux/slab.h> /* diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c index f5de79f29f1e..73661c4ab82a 100644 --- a/sound/core/seq/oss/seq_oss_readq.c +++ b/sound/core/seq/oss/seq_oss_readq.c @@ -25,6 +25,7 @@ #include <sound/seq_oss_legacy.h> #include "../seq_lock.h" #include <linux/wait.h> +#include <linux/slab.h> /* * constants diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index 945a27c34a9d..ee44ab9593c0 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -24,6 +24,7 @@ #include "seq_oss_midi.h" #include "../seq_lock.h" #include <linux/init.h> +#include <linux/slab.h> /* * constants diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c index c440fdacec93..ab59cbfbcaf2 100644 --- a/sound/core/seq/oss/seq_oss_timer.c +++ b/sound/core/seq/oss/seq_oss_timer.c @@ -23,6 +23,7 @@ #include "seq_oss_timer.h" #include "seq_oss_event.h" #include <sound/seq_oss_legacy.h> +#include <linux/slab.h> /* */ diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c index 217424858191..d50338bbc21f 100644 --- a/sound/core/seq/oss/seq_oss_writeq.c +++ b/sound/core/seq/oss/seq_oss_writeq.c @@ -27,6 +27,7 @@ #include "../seq_lock.h" #include "../seq_clientmgr.h" #include <linux/wait.h> +#include <linux/slab.h> /* diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 48eca9ff9ee7..99a485f13648 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -318,6 +318,11 @@ static int snd_seq_open(struct inode *inode, struct file *file) int c, mode; /* client id */ struct snd_seq_client *client; struct snd_seq_user_client *user; + int err; + + err = nonseekable_open(inode, file); + if (err < 0) + return err; if (mutex_lock_interruptible(®ister_mutex)) return -ERESTARTSYS; @@ -2550,6 +2555,7 @@ static const struct file_operations snd_seq_f_ops = .write = snd_seq_write, .open = snd_seq_open, .release = snd_seq_release, + .llseek = no_llseek, .poll = snd_seq_poll, .unlocked_ioctl = snd_seq_ioctl, .compat_ioctl = snd_seq_ioctl_compat, diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c index c956fe462569..81f7c109dc46 100644 --- a/sound/core/seq/seq_compat.c +++ b/sound/core/seq/seq_compat.c @@ -21,6 +21,7 @@ /* This file included from seq.c */ #include <linux/compat.h> +#include <linux/slab.h> struct snd_seq_port_info32 { struct snd_seq_addr addr; /* client/port numbers */ diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c index 77884e62b648..c38b90cf3cb0 100644 --- a/sound/core/seq/seq_system.c +++ b/sound/core/seq/seq_system.c @@ -20,6 +20,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <sound/core.h> #include "seq_system.h" #include "seq_timer.h" diff --git a/sound/core/sound.c b/sound/core/sound.c index 563d1967a0ad..ac42af42b787 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type) EXPORT_SYMBOL(snd_lookup_minor_data); -static int __snd_open(struct inode *inode, struct file *file) +#ifdef CONFIG_MODULES +static struct snd_minor *autoload_device(unsigned int minor) +{ + int dev; + mutex_unlock(&sound_mutex); /* release lock temporarily */ + dev = SNDRV_MINOR_DEVICE(minor); + if (dev == SNDRV_MINOR_CONTROL) { + /* /dev/aloadC? */ + int card = SNDRV_MINOR_CARD(minor); + if (snd_cards[card] == NULL) + snd_request_card(card); + } else if (dev == SNDRV_MINOR_GLOBAL) { + /* /dev/aloadSEQ */ + snd_request_other(minor); + } + mutex_lock(&sound_mutex); /* reacuire lock */ + return snd_minors[minor]; +} +#else /* !CONFIG_MODULES */ +#define autoload_device(minor) NULL +#endif /* CONFIG_MODULES */ + +static int snd_open(struct inode *inode, struct file *file) { unsigned int minor = iminor(inode); struct snd_minor *mptr = NULL; @@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file) if (minor >= ARRAY_SIZE(snd_minors)) return -ENODEV; + mutex_lock(&sound_mutex); mptr = snd_minors[minor]; if (mptr == NULL) { -#ifdef CONFIG_MODULES - int dev = SNDRV_MINOR_DEVICE(minor); - if (dev == SNDRV_MINOR_CONTROL) { - /* /dev/aloadC? */ - int card = SNDRV_MINOR_CARD(minor); - if (snd_cards[card] == NULL) - snd_request_card(card); - } else if (dev == SNDRV_MINOR_GLOBAL) { - /* /dev/aloadSEQ */ - snd_request_other(minor); - } -#ifndef CONFIG_SND_DYNAMIC_MINORS - /* /dev/snd/{controlC?,seq} */ - mptr = snd_minors[minor]; - if (mptr == NULL) -#endif -#endif + mptr = autoload_device(minor); + if (!mptr) { + mutex_unlock(&sound_mutex); return -ENODEV; + } } old_fops = file->f_op; file->f_op = fops_get(mptr->f_ops); if (file->f_op == NULL) { file->f_op = old_fops; - return -ENODEV; + err = -ENODEV; } - if (file->f_op->open) + mutex_unlock(&sound_mutex); + if (err < 0) + return err; + + if (file->f_op->open) { err = file->f_op->open(inode, file); - if (err) { - fops_put(file->f_op); - file->f_op = fops_get(old_fops); + if (err) { + fops_put(file->f_op); + file->f_op = fops_get(old_fops); + } } fops_put(old_fops); return err; } - -/* BKL pushdown: nasty #ifdef avoidance wrapper */ -static int snd_open(struct inode *inode, struct file *file) -{ - int ret; - - lock_kernel(); - ret = __snd_open(inode, file); - unlock_kernel(); - return ret; -} - static const struct file_operations snd_fops = { .owner = THIS_MODULE, diff --git a/sound/core/timer.c b/sound/core/timer.c index 73943651caed..13afb60999b9 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1160,6 +1160,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri, { struct snd_timer_user *tu = timeri->callback_data; struct snd_timer_tread r1; + unsigned long flags; if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE) @@ -1169,9 +1170,9 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri, r1.event = event; r1.tstamp = *tstamp; r1.val = resolution; - spin_lock(&tu->qlock); + spin_lock_irqsave(&tu->qlock, flags); snd_timer_user_append_to_tqueue(tu, &r1); - spin_unlock(&tu->qlock); + spin_unlock_irqrestore(&tu->qlock, flags); kill_fasync(&tu->fasync, SIGIO, POLL_IN); wake_up(&tu->qchange_sleep); } @@ -1237,6 +1238,11 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri, static int snd_timer_user_open(struct inode *inode, struct file *file) { struct snd_timer_user *tu; + int err; + + err = nonseekable_open(inode, file); + if (err < 0) + return err; tu = kzalloc(sizeof(*tu), GFP_KERNEL); if (tu == NULL) @@ -1921,6 +1927,7 @@ static const struct file_operations snd_timer_f_ops = .read = snd_timer_user_read, .open = snd_timer_user_open, .release = snd_timer_user_release, + .llseek = no_llseek, .poll = snd_timer_user_poll, .unlocked_ioctl = snd_timer_user_ioctl, .compat_ioctl = snd_timer_user_ioctl_compat, diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c index 1950ffce2b54..a1282c1c0591 100644 --- a/sound/drivers/ml403-ac97cr.c +++ b/sound/drivers/ml403-ac97cr.c @@ -39,6 +39,7 @@ #include <linux/platform_device.h> #include <linux/ioport.h> +#include <linux/slab.h> #include <linux/io.h> #include <linux/interrupt.h> diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c index 2f8f295d6b0c..da03597fc893 100644 --- a/sound/drivers/mtpav.c +++ b/sound/drivers/mtpav.c @@ -54,7 +54,6 @@ #include <linux/interrupt.h> #include <linux/err.h> #include <linux/platform_device.h> -#include <linux/slab.h> #include <linux/ioport.h> #include <linux/moduleparam.h> #include <sound/core.h> diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index 9284829bf927..8539ab0a0893 100644 --- a/sound/drivers/mts64.c +++ b/sound/drivers/mts64.c @@ -23,6 +23,7 @@ #include <linux/parport.h> #include <linux/spinlock.h> #include <linux/delay.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/initval.h> #include <sound/rawmidi.h> diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c index a54b1dc5cc78..ade3ca52422e 100644 --- a/sound/drivers/opl3/opl3_oss.c +++ b/sound/drivers/opl3/opl3_oss.c @@ -19,7 +19,6 @@ */ #include "opl3_voice.h" -#include <linux/slab.h> static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure); static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg); diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c index 6d57b6441dec..301acb6b9cf9 100644 --- a/sound/drivers/opl3/opl3_synth.c +++ b/sound/drivers/opl3/opl3_synth.c @@ -19,6 +19,7 @@ * */ +#include <linux/slab.h> #include <sound/opl3.h> #include <sound/asound_fm.h> diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c index 01997f24c895..f07e38da59b8 100644 --- a/sound/drivers/opl4/opl4_lib.c +++ b/sound/drivers/opl4/opl4_lib.c @@ -20,6 +20,7 @@ #include "opl4_local.h" #include <sound/initval.h> #include <linux/ioport.h> +#include <linux/slab.h> #include <linux/init.h> #include <asm/io.h> diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c index 1679300b7583..df850b8830a5 100644 --- a/sound/drivers/opl4/opl4_proc.c +++ b/sound/drivers/opl4/opl4_proc.c @@ -49,77 +49,45 @@ static int snd_opl4_mem_proc_release(struct snd_info_entry *entry, return 0; } -static long snd_opl4_mem_proc_read(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *_buf, - unsigned long count, unsigned long pos) +static ssize_t snd_opl4_mem_proc_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *_buf, + size_t count, loff_t pos) { struct snd_opl4 *opl4 = entry->private_data; - long size; char* buf; - size = count; - if (pos + size > entry->size) - size = entry->size - pos; - if (size > 0) { - buf = vmalloc(size); - if (!buf) - return -ENOMEM; - snd_opl4_read_memory(opl4, buf, pos, size); - if (copy_to_user(_buf, buf, size)) { - vfree(buf); - return -EFAULT; - } + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + snd_opl4_read_memory(opl4, buf, pos, count); + if (copy_to_user(_buf, buf, count)) { vfree(buf); - return size; + return -EFAULT; } - return 0; + vfree(buf); + return count; } -static long snd_opl4_mem_proc_write(struct snd_info_entry *entry, void *file_private_data, - struct file *file, const char __user *_buf, - unsigned long count, unsigned long pos) +static ssize_t snd_opl4_mem_proc_write(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, + const char __user *_buf, + size_t count, loff_t pos) { struct snd_opl4 *opl4 = entry->private_data; - long size; char *buf; - size = count; - if (pos + size > entry->size) - size = entry->size - pos; - if (size > 0) { - buf = vmalloc(size); - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, _buf, size)) { - vfree(buf); - return -EFAULT; - } - snd_opl4_write_memory(opl4, buf, pos, size); + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + if (copy_from_user(buf, _buf, count)) { vfree(buf); - return size; - } - return 0; -} - -static long long snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, void *file_private_data, - struct file *file, long long offset, int orig) -{ - switch (orig) { - case SEEK_SET: - file->f_pos = offset; - break; - case SEEK_CUR: - file->f_pos += offset; - break; - case SEEK_END: /* offset is negative */ - file->f_pos = entry->size + offset; - break; - default: - return -EINVAL; + return -EFAULT; } - if (file->f_pos > entry->size) - file->f_pos = entry->size; - return file->f_pos; + snd_opl4_write_memory(opl4, buf, pos, count); + vfree(buf); + return count; } static struct snd_info_entry_ops snd_opl4_mem_proc_ops = { @@ -127,7 +95,6 @@ static struct snd_info_entry_ops snd_opl4_mem_proc_ops = { .release = snd_opl4_mem_proc_release, .read = snd_opl4_mem_proc_read, .write = snd_opl4_mem_proc_write, - .llseek = snd_opl4_mem_proc_llseek, }; int snd_opl4_create_proc(struct snd_opl4 *opl4) diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index e1145ac6e908..d77ffa9a9387 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -7,6 +7,7 @@ */ #include <linux/module.h> +#include <linux/gfp.h> #include <linux/moduleparam.h> #include <linux/interrupt.h> #include <sound/pcm.h> diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c index 60158e2e0eaf..f2b0ba22d9ce 100644 --- a/sound/drivers/portman2x4.c +++ b/sound/drivers/portman2x4.c @@ -42,6 +42,7 @@ #include <linux/parport.h> #include <linux/spinlock.h> #include <linux/delay.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/initval.h> #include <sound/rawmidi.h> diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c index 46df8817c18f..f7a6fbd313e3 100644 --- a/sound/drivers/vx/vx_hwdep.c +++ b/sound/drivers/vx/vx_hwdep.c @@ -22,6 +22,7 @@ #include <linux/device.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <linux/vmalloc.h> #include <sound/core.h> #include <sound/hwdep.h> diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c index fff62cc8607c..971a84a4fa77 100644 --- a/sound/i2c/other/ak4113.c +++ b/sound/i2c/other/ak4113.c @@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device) } int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, - ak4113_write_t *write, const unsigned char pgm[5], + ak4113_write_t *write, const unsigned char *pgm, void *private_data, struct ak4113 **r_ak4113) { struct ak4113 *chip; diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index c4c6ef73f9bf..ee538f1ae846 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -24,6 +24,7 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/init.h> +#include <linux/slab.h> #include <linux/version.h> #include <sound/core.h> #include <sound/tea575x-tuner.h> diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index 8246aae32ab4..fe79a169acb5 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -46,7 +46,6 @@ #include <linux/init.h> #include <linux/err.h> #include <linux/isa.h> -#include <linux/slab.h> #include <linux/pnp.h> #include <linux/moduleparam.h> #include <sound/core.h> diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index cc15d1d65a22..999dc1e0fdbd 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -22,7 +22,6 @@ #include <linux/init.h> #include <linux/err.h> #include <linux/isa.h> -#include <linux/slab.h> #include <linux/pnp.h> #include <linux/moduleparam.h> #include <sound/core.h> diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 9a43baae7250..fb4d6b34bbca 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -80,7 +80,6 @@ #include <linux/init.h> #include <linux/err.h> #include <linux/isa.h> -#include <linux/slab.h> #include <linux/pnp.h> #include <linux/isapnp.h> #include <linux/moduleparam.h> diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c index 2803e227aec9..2ccb3fadd7be 100644 --- a/sound/isa/gus/gus_mem_proc.c +++ b/sound/isa/gus/gus_mem_proc.c @@ -31,52 +31,21 @@ struct gus_proc_private { struct snd_gus_card * gus; }; -static long snd_gf1_mem_proc_dump(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_gf1_mem_proc_dump(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { - long size; struct gus_proc_private *priv = entry->private_data; struct snd_gus_card *gus = priv->gus; int err; - size = count; - if (pos + size > priv->size) - size = (long)priv->size - pos; - if (size > 0) { - if ((err = snd_gus_dram_read(gus, buf, pos, size, priv->rom)) < 0) - return err; - return size; - } - return 0; + err = snd_gus_dram_read(gus, buf, pos, count, priv->rom); + if (err < 0) + return err; + return count; } -static long long snd_gf1_mem_proc_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - long long offset, - int orig) -{ - struct gus_proc_private *priv = entry->private_data; - - switch (orig) { - case SEEK_SET: - file->f_pos = offset; - break; - case SEEK_CUR: - file->f_pos += offset; - break; - case SEEK_END: /* offset is negative */ - file->f_pos = priv->size + offset; - break; - default: - return -EINVAL; - } - if (file->f_pos > priv->size) - file->f_pos = priv->size; - return file->f_pos; -} - static void snd_gf1_mem_proc_free(struct snd_info_entry *entry) { struct gus_proc_private *priv = entry->private_data; @@ -85,7 +54,6 @@ static void snd_gf1_mem_proc_free(struct snd_info_entry *entry) static struct snd_info_entry_ops snd_gf1_mem_proc_ops = { .read = snd_gf1_mem_proc_dump, - .llseek = snd_gf1_mem_proc_llseek, }; int snd_gf1_mem_proc_init(struct snd_gus_card * gus) diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 534a6eced2b8..c7b80e4730fc 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -26,7 +26,6 @@ #include <linux/err.h> #include <linux/isa.h> #include <linux/delay.h> -#include <linux/slab.h> #include <linux/pnp.h> #include <linux/moduleparam.h> #include <asm/dma.h> diff --git a/sound/isa/msnd/msnd_midi.c b/sound/isa/msnd/msnd_midi.c index 4be562b2cf21..787495674235 100644 --- a/sound/isa/msnd/msnd_midi.c +++ b/sound/isa/msnd/msnd_midi.c @@ -25,6 +25,7 @@ */ #include <linux/io.h> +#include <linux/slab.h> #include <linux/delay.h> #include <linux/ioport.h> #include <linux/errno.h> diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 0481a55334b9..265abcce9dba 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -24,7 +24,6 @@ #include <linux/isa.h> #include <linux/interrupt.h> #include <linux/pm.h> -#include <linux/slab.h> #include <linux/pnp.h> #include <linux/moduleparam.h> #include <sound/core.h> diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 5913717c1be6..8c24102d0d93 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -27,7 +27,6 @@ #include <linux/isa.h> #include <linux/pnp.h> #include <linux/delay.h> -#include <linux/slab.h> #include <linux/ioport.h> #include <linux/moduleparam.h> #include <asm/io.h> diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index becd90d7536d..c35dc68930dc 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -27,7 +27,6 @@ #include <linux/err.h> #include <linux/isa.h> #include <linux/delay.h> -#include <linux/slab.h> #include <linux/pnp.h> #include <linux/moduleparam.h> #include <asm/io.h> @@ -217,8 +216,9 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, if (isapnp && chip->mc_base) /* PnP resource gives the least 10 bits */ chip->mc_base |= 0xc00; + else #endif /* CONFIG_PNP */ - else { + { chip->mc_base = 0xf8c; chip->mc_base_size = opti9xx_mc_size[hardware]; } diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c index 91dc3d83e2cf..ccedbfed061a 100644 --- a/sound/isa/sb/emu8000_pcm.c +++ b/sound/isa/sb/emu8000_pcm.c @@ -20,6 +20,7 @@ #include "emu8000_local.h" #include <linux/init.h> +#include <linux/slab.h> #include <sound/initval.h> #include <sound/pcm.h> diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c index cafc3a7316a8..ff18286fef9d 100644 --- a/sound/isa/sb/es968.c +++ b/sound/isa/sb/es968.c @@ -93,7 +93,7 @@ static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard, return err; } port[dev] = pnp_port_start(pdev, 0); - dma8[dev] = pnp_dma(pdev, 1); + dma8[dev] = pnp_dma(pdev, 0); irq[dev] = pnp_irq(pdev, 0); return 0; diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 519c36346dec..4d1c5a300ff8 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c @@ -21,7 +21,6 @@ #include <asm/dma.h> #include <linux/init.h> -#include <linux/slab.h> #include <linux/pnp.h> #include <linux/err.h> #include <linux/isa.h> diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index 3cd57ee54660..81284a8fa0ce 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c @@ -22,7 +22,6 @@ #include <linux/init.h> #include <linux/err.h> #include <linux/isa.h> -#include <linux/slab.h> #include <linux/ioport.h> #include <linux/moduleparam.h> #include <sound/core.h> diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index a34ae7b1f7d0..711670e4a425 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -21,7 +21,6 @@ #include <linux/init.h> #include <linux/interrupt.h> -#include <linux/slab.h> #include <linux/err.h> #include <linux/isa.h> #include <linux/pnp.h> diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c index 2bb1cee09255..657e2d6c01ac 100644 --- a/sound/isa/wavefront/wavefront_fx.c +++ b/sound/isa/wavefront/wavefront_fx.c @@ -20,6 +20,7 @@ #include <linux/init.h> #include <linux/time.h> #include <linux/wait.h> +#include <linux/slab.h> #include <linux/firmware.h> #include <sound/core.h> #include <sound/snd_wavefront.h> diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 5d4ff48c4345..4fb7b19ff393 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -28,6 +28,7 @@ #include <linux/wait.h> #include <linux/firmware.h> #include <linux/moduleparam.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/snd_wavefront.h> #include <sound/initval.h> diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c index 9a88cdfd952a..453d343550a8 100644 --- a/sound/mips/hal2.c +++ b/sound/mips/hal2.c @@ -25,6 +25,7 @@ #include <linux/dma-mapping.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/slab.h> #include <asm/sgi/hpc3.h> #include <asm/sgi/ip22.h> diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 6aff217379d9..717604c00f0a 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c @@ -25,11 +25,11 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/spinlock.h> -#include <linux/gfp.h> #include <linux/interrupt.h> #include <linux/dma-mapping.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/slab.h> #include <asm/ip32/ip32_ints.h> #include <asm/ip32/mace.h> diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c index d12bd98a37ba..24793c5b65ac 100644 --- a/sound/oss/ad1848.c +++ b/sound/oss/ad1848.c @@ -45,6 +45,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/stddef.h> +#include <linux/slab.h> #include <linux/isapnp.h> #include <linux/pnp.h> #include <linux/spinlock.h> diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c index 1bfcf7e88546..bcc3e8e07122 100644 --- a/sound/oss/dmabuf.c +++ b/sound/oss/dmabuf.c @@ -26,6 +26,7 @@ #define SAMPLE_ROUNDUP 0 #include <linux/mm.h> +#include <linux/gfp.h> #include "sound_config.h" #define DMAP_FREE_ON_CLOSE 0 diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c index 24d152ccf80d..52d06a334e8f 100644 --- a/sound/oss/kahlua.c +++ b/sound/oss/kahlua.c @@ -31,6 +31,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/slab.h> #include "sound_config.h" diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c index 0af9d24feb8f..25e4609f8339 100644 --- a/sound/oss/mpu401.c +++ b/sound/oss/mpu401.c @@ -19,6 +19,7 @@ */ #include <linux/module.h> +#include <linux/slab.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/spinlock.h> diff --git a/sound/oss/msnd.c b/sound/oss/msnd.c index 21eb6dce46df..c0cc951ba97d 100644 --- a/sound/oss/msnd.c +++ b/sound/oss/msnd.c @@ -24,7 +24,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/types.h> #include <linux/delay.h> diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c index bf27e008f465..a1e3f9671bea 100644 --- a/sound/oss/msnd_pinnacle.c +++ b/sound/oss/msnd_pinnacle.c @@ -35,12 +35,12 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/slab.h> #include <linux/types.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/smp_lock.h> +#include <linux/gfp.h> #include <asm/irq.h> #include <asm/io.h> #include "sound_config.h" diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c index 7781c13c1476..938c48c43585 100644 --- a/sound/oss/opl3.c +++ b/sound/oss/opl3.c @@ -24,6 +24,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/delay.h> diff --git a/sound/oss/sb_card.c b/sound/oss/sb_card.c index 7de18b58f2cd..84ef4d06c1c2 100644 --- a/sound/oss/sb_card.c +++ b/sound/oss/sb_card.c @@ -24,6 +24,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/slab.h> #include <linux/init.h> #include "sound_config.h" #include "sb_mixer.h" diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c index ce4db49291f7..7d42c5418d1b 100644 --- a/sound/oss/sb_common.c +++ b/sound/oss/sb_common.c @@ -31,6 +31,7 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/spinlock.h> +#include <linux/slab.h> #include "sound_config.h" #include "sound_firmware.h" diff --git a/sound/oss/sb_midi.c b/sound/oss/sb_midi.c index 8b796704e112..f139028e85c0 100644 --- a/sound/oss/sb_midi.c +++ b/sound/oss/sb_midi.c @@ -12,6 +12,7 @@ */ #include <linux/spinlock.h> +#include <linux/slab.h> #include "sound_config.h" diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c index fad1a4f25ad6..2039d31b7e22 100644 --- a/sound/oss/sb_mixer.c +++ b/sound/oss/sb_mixer.c @@ -16,6 +16,8 @@ * Stanislav Voronyi <stas@esc.kharkov.com> : Support for AWE 3DSE device (Jun 7 1999) */ +#include <linux/slab.h> + #include "sound_config.h" #define __SB_MIXER_C__ diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c index c79874696bec..e85789e53816 100644 --- a/sound/oss/sequencer.c +++ b/sound/oss/sequencer.c @@ -1631,8 +1631,6 @@ unsigned long compute_finetune(unsigned long base_freq, int bend, int range, } semitones = bend / 100; - if (semitones > 99) - semitones = 99; cents = bend % 100; amount = (int) (semitone_tuning[semitones] * multiplier * cent_tuning[cents]) / 10000; diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index fde7c12fe5da..2d9c51312622 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c @@ -36,7 +36,6 @@ #include <asm/dma.h> #include <asm/io.h> #include <linux/wait.h> -#include <linux/slab.h> #include <linux/ioport.h> #include <linux/major.h> #include <linux/delay.h> diff --git a/sound/oss/uart401.c b/sound/oss/uart401.c index a446b826d5fc..8e514a676a0d 100644 --- a/sound/oss/uart401.c +++ b/sound/oss/uart401.c @@ -24,6 +24,7 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/spinlock.h> #include "sound_config.h" diff --git a/sound/oss/v_midi.c b/sound/oss/v_midi.c index 103940fd5b4f..f0b4151d9b17 100644 --- a/sound/oss/v_midi.c +++ b/sound/oss/v_midi.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/spinlock.h> #include "sound_config.h" diff --git a/sound/oss/vidc.c b/sound/oss/vidc.c index 725fef0f59a3..ac39a531df19 100644 --- a/sound/oss/vidc.c +++ b/sound/oss/vidc.c @@ -17,6 +17,7 @@ * We currently support a mixer device, but it is currently non-functional. */ +#include <linux/gfp.h> #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> @@ -363,13 +364,13 @@ static void vidc_audio_trigger(int dev, int enable_bits) struct audio_operations *adev = audio_devs[dev]; if (enable_bits & PCM_ENABLE_OUTPUT) { - if (!(adev->flags & DMA_ACTIVE)) { + if (!(adev->dmap_out->flags & DMA_ACTIVE)) { unsigned long flags; local_irq_save(flags); /* prevent recusion */ - adev->flags |= DMA_ACTIVE; + adev->dmap_out->flags |= DMA_ACTIVE; dma_interrupt = vidc_audio_dma_interrupt; vidc_sound_dma_irq(0, NULL); diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c index 6713110bdc75..20b3b325aa80 100644 --- a/sound/oss/vwsnd.c +++ b/sound/oss/vwsnd.c @@ -149,6 +149,7 @@ #include <linux/wait.h> #include <linux/interrupt.h> #include <linux/mutex.h> +#include <linux/slab.h> #include <asm/visws/cobalt.h> diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c index 2c63bb9da74a..e688dde6bbde 100644 --- a/sound/oss/waveartist.c +++ b/sound/oss/waveartist.c @@ -35,6 +35,7 @@ #include <linux/module.h> #include <linux/init.h> +#include <linux/slab.h> #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/delay.h> diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 1caf5e3c1f6a..e68c98ef4041 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -1852,12 +1852,14 @@ static unsigned int ad1981_jacks_blacklist[] = { 0x10140523, /* Thinkpad R40 */ 0x10140534, /* Thinkpad X31 */ 0x10140537, /* Thinkpad T41p */ + 0x1014053e, /* Thinkpad R40e */ 0x10140554, /* Thinkpad T42p/R50p */ 0x10140567, /* Thinkpad T43p 2668-G7U */ 0x10140581, /* Thinkpad X41-2527 */ 0x10280160, /* Dell Dimension 2400 */ 0x104380b0, /* Asus A7V8X-MX */ 0x11790241, /* Toshiba Satellite A-15 S127 */ + 0x1179ff10, /* Toshiba P500 */ 0x144dc01a, /* Samsung NP-X20C004/SEG */ 0 /* end */ }; diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c index 73b17d526c8b..6320bf084e47 100644 --- a/sound/pci/ac97/ac97_proc.c +++ b/sound/pci/ac97/ac97_proc.c @@ -22,7 +22,6 @@ * */ -#include <linux/slab.h> #include <linux/mutex.h> #include <sound/core.h> diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index d75cf7b06426..6cf1de8042e8 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -68,7 +68,6 @@ #include <asm/io.h> #include <linux/init.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/gameport.h> #include <linux/moduleparam.h> #include <linux/dma-mapping.h> diff --git a/sound/pci/aw2/aw2-saa7146.c b/sound/pci/aw2/aw2-saa7146.c index 296123ab74f7..8afd8b5d1ac7 100644 --- a/sound/pci/aw2/aw2-saa7146.c +++ b/sound/pci/aw2/aw2-saa7146.c @@ -25,7 +25,6 @@ #include <linux/init.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <asm/system.h> diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index 8f443a9d61ec..85fd315d9999 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c @@ -63,7 +63,6 @@ #include <linux/delay.h> #include <linux/init.h> #include <linux/interrupt.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <sound/core.h> #include <sound/initval.h> diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c index 0470461cc03e..ba96428c9f4c 100644 --- a/sound/pci/ca0106/ca0106_proc.c +++ b/sound/pci/ca0106/ca0106_proc.c @@ -63,7 +63,6 @@ #include <linux/delay.h> #include <linux/init.h> #include <linux/interrupt.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <sound/core.h> #include <sound/initval.h> diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 1ded64e05643..329968edca9b 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -941,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci struct snd_pcm_substream *substream) { size_t ptr; - unsigned int reg; + unsigned int reg, rem, tries; + if (!rec->running) return 0; #if 1 // this seems better.. reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; - ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1); - ptr >>= rec->shift; + for (tries = 0; tries < 3; tries++) { + rem = snd_cmipci_read_w(cm, reg); + if (rem < rec->dma_size) + goto ok; + } + printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem); + return SNDRV_PCM_POS_XRUN; +ok: + ptr = (rec->dma_size - (rem + 1)) >> rec->shift; #else reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1; ptr = snd_cmipci_read(cm, reg) - rec->offset; diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index 9edc65059e3e..6772070ed492 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -1139,40 +1139,28 @@ static void snd_cs4281_proc_read(struct snd_info_entry *entry, snd_iprintf(buffer, "Spurious end IRQs : %u\n", chip->spurious_dtc_irq); } -static long snd_cs4281_BA0_read(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_cs4281_BA0_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { - long size; struct cs4281 *chip = entry->private_data; - size = count; - if (pos + size > CS4281_BA0_SIZE) - size = (long)CS4281_BA0_SIZE - pos; - if (size > 0) { - if (copy_to_user_fromio(buf, chip->ba0 + pos, size)) - return -EFAULT; - } - return size; + if (copy_to_user_fromio(buf, chip->ba0 + pos, count)) + return -EFAULT; + return count; } -static long snd_cs4281_BA1_read(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_cs4281_BA1_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { - long size; struct cs4281 *chip = entry->private_data; - size = count; - if (pos + size > CS4281_BA1_SIZE) - size = (long)CS4281_BA1_SIZE - pos; - if (size > 0) { - if (copy_to_user_fromio(buf, chip->ba1 + pos, size)) - return -EFAULT; - } - return size; + if (copy_to_user_fromio(buf, chip->ba1 + pos, count)) + return -EFAULT; + return count; } static struct snd_info_entry_ops snd_cs4281_proc_ops_BA0 = { diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 3f99a5e8528c..aad37082cb6e 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -2657,21 +2657,16 @@ static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { } * proc interface */ -static long snd_cs46xx_io_read(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_cs46xx_io_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { - long size; struct snd_cs46xx_region *region = entry->private_data; - size = count; - if (pos + (size_t)size > region->size) - size = region->size - pos; - if (size > 0) { - if (copy_to_user_fromio(buf, region->remap_addr + pos, size)) - return -EFAULT; - } - return size; + if (copy_to_user_fromio(buf, region->remap_addr + pos, count)) + return -EFAULT; + return count; } static struct snd_info_entry_ops snd_cs46xx_proc_io_ops = { diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c index 207479a641cf..bc07e275d4d4 100644 --- a/sound/pci/cs5530.c +++ b/sound/pci/cs5530.c @@ -39,6 +39,7 @@ #include <linux/delay.h> #include <linux/moduleparam.h> #include <linux/pci.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/sb.h> #include <sound/initval.h> diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index 0f48a871f17b..f16bc8aad6ed 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -23,7 +23,6 @@ */ #include <linux/init.h> -#include <linux/slab.h> #include <linux/pci.h> #include <sound/core.h> #include <sound/control.h> diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c index 564c33b60953..a3301cc4ab82 100644 --- a/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/sound/pci/cs5535audio/cs5535audio_pm.c @@ -19,7 +19,6 @@ */ #include <linux/init.h> -#include <linux/slab.h> #include <linux/pci.h> #include <linux/delay.h> #include <sound/core.h> diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 480cb1e905b6..1bff80cde0a2 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -24,6 +24,7 @@ #include "ctdaio.h" #include "cttimer.h" #include <linux/delay.h> +#include <linux/slab.h> #include <sound/pcm.h> #include <sound/control.h> #include <sound/asoundef.h> diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index d0dc227fbdd3..85ab43e89212 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c @@ -17,6 +17,7 @@ #include "ctpcm.h" #include "cttimer.h" +#include <linux/slab.h> #include <sound/pcm.h> /* Hardware descriptions for playback */ diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c index a65bafe0800f..fe7ad64dccd7 100644 --- a/sound/pci/echoaudio/darla20.c +++ b/sound/pci/echoaudio/darla20.c @@ -40,9 +40,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c index 0a6c50bcd758..d1fd34b1a8e3 100644 --- a/sound/pci/echoaudio/darla24.c +++ b/sound/pci/echoaudio/darla24.c @@ -44,9 +44,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c index f5142796989b..1dffdc54416d 100644 --- a/sound/pci/echoaudio/echo3g.c +++ b/sound/pci/echoaudio/echo3g.c @@ -51,9 +51,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 8dab82d7d19d..668a5ec04499 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci, goto ctl_error; #endif - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); + err = snd_card_register(card); + if (err < 0) goto ctl_error; - } snd_printk(KERN_INFO "Card registered: %s\n", card->longname); pci_set_drvdata(pci, chip); diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c index 2364f8a1bc21..050e54aa693f 100644 --- a/sound/pci/echoaudio/gina20.c +++ b/sound/pci/echoaudio/gina20.c @@ -44,9 +44,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c index 616b55825a19..5748fc6d29d6 100644 --- a/sound/pci/echoaudio/gina24.c +++ b/sound/pci/echoaudio/gina24.c @@ -50,9 +50,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c index 776175c0bdad..4ae5e35cb5f1 100644 --- a/sound/pci/echoaudio/indigo.c +++ b/sound/pci/echoaudio/indigo.c @@ -42,9 +42,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c index 8816b0bd2ba6..3550715bab1c 100644 --- a/sound/pci/echoaudio/indigodj.c +++ b/sound/pci/echoaudio/indigodj.c @@ -42,9 +42,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/indigodjx.c b/sound/pci/echoaudio/indigodjx.c index b1e3652f2f48..19b191fd0120 100644 --- a/sound/pci/echoaudio/indigodjx.c +++ b/sound/pci/echoaudio/indigodjx.c @@ -42,10 +42,10 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> #include <linux/io.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c index 1035125336d6..a9fcedf317a4 100644 --- a/sound/pci/echoaudio/indigoio.c +++ b/sound/pci/echoaudio/indigoio.c @@ -43,9 +43,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/indigoiox.c b/sound/pci/echoaudio/indigoiox.c index 60b7cb2753cf..bcdfac63212c 100644 --- a/sound/pci/echoaudio/indigoiox.c +++ b/sound/pci/echoaudio/indigoiox.c @@ -43,10 +43,10 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> #include <linux/io.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c index 8c3f5c5b5301..d3a98c5dac86 100644 --- a/sound/pci/echoaudio/layla20.c +++ b/sound/pci/echoaudio/layla20.c @@ -49,9 +49,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c index ed1cc0abc2b8..2a1dca6dce17 100644 --- a/sound/pci/echoaudio/layla24.c +++ b/sound/pci/echoaudio/layla24.c @@ -51,9 +51,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c index cc2bbfc65327..9cdf14cfdd74 100644 --- a/sound/pci/echoaudio/mia.c +++ b/sound/pci/echoaudio/mia.c @@ -50,9 +50,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c index 3e7e01824b40..1047be405ebe 100644 --- a/sound/pci/echoaudio/mona.c +++ b/sound/pci/echoaudio/mona.c @@ -48,9 +48,9 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/firmware.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include <sound/control.h> diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c index baa7cd508cd8..bc38dd4d071f 100644 --- a/sound/pci/emu10k1/emuproc.c +++ b/sound/pci/emu10k1/emuproc.c @@ -341,15 +341,17 @@ static void snd_emu10k1_proc_acode_read(struct snd_info_entry *entry, #define TOTAL_SIZE_CODE (0x200*8) #define A_TOTAL_SIZE_CODE (0x400*8) -static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry, - void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_emu10k1_fx8010_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { - long size; struct snd_emu10k1 *emu = entry->private_data; unsigned int offset; int tram_addr = 0; + unsigned int *tmp; + long res; + unsigned int idx; if (!strcmp(entry->name, "fx8010_tram_addr")) { offset = TANKMEMADDRREGBASE; @@ -361,30 +363,25 @@ static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry, } else { offset = emu->audigy ? A_FXGPREGBASE : FXGPREGBASE; } - size = count; - if (pos + size > entry->size) - size = (long)entry->size - pos; - if (size > 0) { - unsigned int *tmp; - long res; - unsigned int idx; - if ((tmp = kmalloc(size + 8, GFP_KERNEL)) == NULL) - return -ENOMEM; - for (idx = 0; idx < ((pos & 3) + size + 3) >> 2; idx++) - if (tram_addr && emu->audigy) { - tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0) >> 11; - tmp[idx] |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20; - } else - tmp[idx] = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0); - if (copy_to_user(buf, ((char *)tmp) + (pos & 3), size)) - res = -EFAULT; - else { - res = size; + + tmp = kmalloc(count + 8, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + for (idx = 0; idx < ((pos & 3) + count + 3) >> 2; idx++) { + unsigned int val; + val = snd_emu10k1_ptr_read(emu, offset + idx + (pos >> 2), 0); + if (tram_addr && emu->audigy) { + val >>= 11; + val |= snd_emu10k1_ptr_read(emu, 0x100 + idx + (pos >> 2), 0) << 20; } - kfree(tmp); - return res; + tmp[idx] = val; } - return 0; + if (copy_to_user(buf, ((char *)tmp) + (pos & 3), count)) + res = -EFAULT; + else + res = count; + kfree(tmp); + return res; } static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 6a47672f930a..ffb1ddb8dc28 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -22,6 +22,7 @@ */ #include <linux/pci.h> +#include <linux/gfp.h> #include <linux/time.h> #include <linux/mutex.h> diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index e4581a42ace5..29714c818b53 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -21,6 +21,7 @@ #include <linux/input.h> #include <linux/pci.h> +#include <linux/slab.h> #include <linux/workqueue.h> #include <sound/core.h> #include "hda_beep.h" diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 5bd7cf45f3a5..0e76ac2b2ace 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1806,6 +1806,8 @@ int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl, item->nid = nid; return 0; } + printk(KERN_ERR "hda-codec: no NID for mapping control %s:%d:%d\n", + kctl->id.name, kctl->id.index, index); return -EINVAL; } EXPORT_SYMBOL_HDA(snd_hda_add_nid); @@ -2884,7 +2886,7 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus) list_for_each_entry(codec, &bus->codec_list, list) { int err = snd_hda_codec_build_controls(codec); if (err < 0) { - printk(KERN_ERR "hda_codec: cannot build controls" + printk(KERN_ERR "hda_codec: cannot build controls " "for #%d (error %d)\n", codec->addr, err); err = snd_hda_codec_reset(codec); if (err < 0) { diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index dcd22446cfc7..d8da18a9e98b 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -22,6 +22,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <sound/core.h> #include <asm/unaligned.h> #include "hda_codec.h" diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 43b7cfb7cffd..cec68152dcb1 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2269,8 +2269,12 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), + SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB), + SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), {} }; @@ -2358,7 +2362,9 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) static struct snd_pci_quirk msi_black_list[] __devinitdata = { SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ + SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ + SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */ {} }; @@ -2377,6 +2383,13 @@ static void __devinit check_msi(struct azx *chip) "hda_intel: msi for device %04x:%04x set to %d\n", q->subvendor, q->subdevice, q->value); chip->msi = q->value; + return; + } + + /* NVidia chipsets seem to cause troubles with MSI */ + if (chip->driver_type == AZX_DRIVER_NVIDIA) { + printk(KERN_INFO "hda_intel: Disable MSI for Nvidia chipset\n"); + chip->msi = 0; } } @@ -2705,6 +2718,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH }, /* PCH */ { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH }, + { PCI_DEVICE(0x8086, 0x3b57), .driver_data = AZX_DRIVER_ICH }, /* CPT */ { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, /* SCH */ diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index e6d1bdff1b6e..e9fdfc4b1c57 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -519,14 +519,6 @@ static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) ad198x_power_eapd(codec); return 0; } - -static int ad198x_resume(struct hda_codec *codec) -{ - ad198x_init(codec); - snd_hda_codec_resume_amp(codec); - snd_hda_codec_resume_cache(codec); - return 0; -} #endif static struct hda_codec_ops ad198x_patch_ops = { @@ -539,7 +531,6 @@ static struct hda_codec_ops ad198x_patch_ops = { #endif #ifdef SND_HDA_NEEDS_RESUME .suspend = ad198x_suspend, - .resume = ad198x_resume, #endif .reboot_notify = ad198x_shutup, }; @@ -1896,6 +1887,14 @@ static int patch_ad1981(struct hda_codec *codec) case AD1981_THINKPAD: spec->mixers[0] = ad1981_thinkpad_mixers; spec->input_mux = &ad1981_thinkpad_capture_source; + /* set the upper-limit for mixer amp to 0dB for avoiding the + * possible damage by overloading + */ + snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, + (0x17 << AC_AMPCAP_OFFSET_SHIFT) | + (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (1 << AC_AMPCAP_MUTE_SHIFT)); break; case AD1981_TOSHIBA: spec->mixers[0] = ad1981_hp_mixers; diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 7de782a5b8f4..350ee8ac4153 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -766,7 +766,7 @@ static int build_input(struct hda_codec *codec) for (n = 0; n < AUTO_PIN_LAST; n++) { if (!spec->adc_nid[n]) continue; - err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]); + err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]); if (err < 0) return err; } diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 194a28c54992..feabb44c7ca4 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1195,10 +1195,12 @@ static int patch_cxt5045(struct hda_codec *codec) switch (codec->subsystem_id >> 16) { case 0x103c: + case 0x1631: case 0x1734: - /* HP & Fujitsu-Siemens laptops have really bad sound over 0dB - * on NID 0x17. Fix max PCM level to 0 dB - * (originally it has 0x2b steps with 0dB offset 0x14) + case 0x17aa: + /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have + * really bad sound over 0dB on NID 0x17. Fix max PCM level to + * 0 dB (originally it has 0x2b steps with 0dB offset 0x14) */ snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, (0x14 << AC_AMPCAP_OFFSET_SHIFT) | @@ -1591,6 +1593,21 @@ static int patch_cxt5047(struct hda_codec *codec) #endif } spec->vmaster_nid = 0x13; + + switch (codec->subsystem_id >> 16) { + case 0x103c: + /* HP laptops have really bad sound over 0 dB on NID 0x10. + * Fix max PCM level to 0 dB (originally it has 0x1e steps + * with 0 dB offset 0x17) + */ + snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT, + (0x17 << AC_AMPCAP_OFFSET_SHIFT) | + (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (1 << AC_AMPCAP_MUTE_SHIFT)); + break; + } + return 0; } @@ -2827,6 +2844,10 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { CXT5066_DELL_LAPTOP), SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), + SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), + SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), + SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), {} }; diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 70669a246902..3c10c0b149f4 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c @@ -538,8 +538,6 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) * patch entries */ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { - { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, - { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x10de0002, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, { .id = 0x10de0003, .name = "MCP77/78 HDMI", @@ -550,12 +548,16 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { .patch = patch_nvhdmi_8ch_7x }, { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x }, - { .id = 0x10de000c, .name = "MCP89 HDMI", + { .id = 0x10de000a, .name = "GT220 HDMI", .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de000b, .name = "GT21x HDMI", .patch = patch_nvhdmi_8ch_89 }, + { .id = 0x10de000c, .name = "MCP89 HDMI", + .patch = patch_nvhdmi_8ch_89 }, { .id = 0x10de000d, .name = "GT240 HDMI", .patch = patch_nvhdmi_8ch_89 }, + { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, + { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, {} /* terminator */ }; @@ -564,11 +566,12 @@ MODULE_ALIAS("snd-hda-codec-id:10de0003"); MODULE_ALIAS("snd-hda-codec-id:10de0005"); MODULE_ALIAS("snd-hda-codec-id:10de0006"); MODULE_ALIAS("snd-hda-codec-id:10de0007"); -MODULE_ALIAS("snd-hda-codec-id:10de0067"); -MODULE_ALIAS("snd-hda-codec-id:10de8001"); -MODULE_ALIAS("snd-hda-codec-id:10de000c"); +MODULE_ALIAS("snd-hda-codec-id:10de000a"); MODULE_ALIAS("snd-hda-codec-id:10de000b"); +MODULE_ALIAS("snd-hda-codec-id:10de000c"); MODULE_ALIAS("snd-hda-codec-id:10de000d"); +MODULE_ALIAS("snd-hda-codec-id:10de0067"); +MODULE_ALIAS("snd-hda-codec-id:10de8001"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec"); diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5d2fbb87b871..886d8e46bb37 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -230,6 +230,7 @@ enum { ALC888_ACER_ASPIRE_7730G, ALC883_MEDION, ALC883_MEDION_MD2, + ALC883_MEDION_WIM2160, ALC883_LAPTOP_EAPD, ALC883_LENOVO_101E_2ch, ALC883_LENOVO_NB0763, @@ -411,6 +412,8 @@ static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id); if (mux_idx >= spec->num_mux_defs) mux_idx = 0; + if (!spec->input_mux[mux_idx].num_items && mux_idx > 0) + mux_idx = 0; return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo); } @@ -439,6 +442,8 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; imux = &spec->input_mux[mux_idx]; + if (!imux->num_items && mux_idx > 0) + imux = &spec->input_mux[0]; type = get_wcaps_type(get_wcaps(codec, nid)); if (type == AC_WID_AUD_MIX) { @@ -1385,22 +1390,31 @@ struct alc_fixup { static void alc_pick_fixup(struct hda_codec *codec, const struct snd_pci_quirk *quirk, - const struct alc_fixup *fix) + const struct alc_fixup *fix, + int pre_init) { const struct alc_pincfg *cfg; quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); if (!quirk) return; - fix += quirk->value; cfg = fix->pins; - if (cfg) { + if (pre_init && cfg) { +#ifdef CONFIG_SND_DEBUG_VERBOSE + snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", + codec->chip_name, quirk->name); +#endif for (; cfg->nid; cfg++) snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); } - if (fix->verbs) + if (!pre_init && fix->verbs) { +#ifdef CONFIG_SND_DEBUG_VERBOSE + snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", + codec->chip_name, quirk->name); +#endif add_verb(codec->spec, fix->verbs); + } } static int alc_read_coef_idx(struct hda_codec *codec, @@ -1617,6 +1631,11 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { */ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { +/* Route to built-in subwoofer as well as speakers */ + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, /* Bias voltage on for external mic port */ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, /* Front Mic: set to PIN_IN (empty by default) */ @@ -1628,10 +1647,12 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { /* Enable speaker output */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, /* Enable headphone output */ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, { } }; @@ -2528,8 +2549,6 @@ static int alc_build_controls(struct hda_codec *codec) return err; } - alc_free_kctls(codec); /* no longer needed */ - /* assign Capture Source enums to NID */ kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); if (!kctl) @@ -2598,6 +2617,9 @@ static int alc_build_controls(struct hda_codec *codec) } } } + + alc_free_kctls(codec); /* no longer needed */ + return 0; } @@ -4121,7 +4143,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), - SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), + SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), @@ -4796,6 +4818,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) } } +static void alc880_auto_init_input_src(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int c; + + for (c = 0; c < spec->num_adc_nids; c++) { + unsigned int mux_idx; + const struct hda_input_mux *imux; + mux_idx = c >= spec->num_mux_defs ? 0 : c; + imux = &spec->input_mux[mux_idx]; + if (!imux->num_items && mux_idx > 0) + imux = &spec->input_mux[0]; + if (imux) + snd_hda_codec_write(codec, spec->adc_nids[c], 0, + AC_VERB_SET_CONNECT_SEL, + imux->items[0].index); + } +} + /* parse the BIOS configuration and set up the alc_spec */ /* return 1 if successful, 0 if the proper config is not found, * or a negative error code @@ -4874,6 +4915,7 @@ static void alc880_auto_init(struct hda_codec *codec) alc880_auto_init_multi_out(codec); alc880_auto_init_extra_out(codec); alc880_auto_init_analog_input(codec); + alc880_auto_init_input_src(codec); if (spec->unsol_event) alc_inithook(codec); } @@ -4979,6 +5021,70 @@ static void set_capture_mixer(struct hda_codec *codec) } } +/* fill adc_nids (and capsrc_nids) containing all active input pins */ +static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, + int num_nids) +{ + struct alc_spec *spec = codec->spec; + int n; + hda_nid_t fallback_adc = 0, fallback_cap = 0; + + for (n = 0; n < num_nids; n++) { + hda_nid_t adc, cap; + hda_nid_t conn[HDA_MAX_NUM_INPUTS]; + int nconns, i, j; + + adc = nids[n]; + if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) + continue; + cap = adc; + nconns = snd_hda_get_connections(codec, cap, conn, + ARRAY_SIZE(conn)); + if (nconns == 1) { + cap = conn[0]; + nconns = snd_hda_get_connections(codec, cap, conn, + ARRAY_SIZE(conn)); + } + if (nconns <= 0) + continue; + if (!fallback_adc) { + fallback_adc = adc; + fallback_cap = cap; + } + for (i = 0; i < AUTO_PIN_LAST; i++) { + hda_nid_t nid = spec->autocfg.input_pins[i]; + if (!nid) + continue; + for (j = 0; j < nconns; j++) { + if (conn[j] == nid) + break; + } + if (j >= nconns) + break; + } + if (i >= AUTO_PIN_LAST) { + int num_adcs = spec->num_adc_nids; + spec->private_adc_nids[num_adcs] = adc; + spec->private_capsrc_nids[num_adcs] = cap; + spec->num_adc_nids++; + spec->adc_nids = spec->private_adc_nids; + if (adc != cap) + spec->capsrc_nids = spec->private_capsrc_nids; + } + } + if (!spec->num_adc_nids) { + printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" + " using fallback 0x%x\n", + codec->chip_name, fallback_adc); + spec->private_adc_nids[0] = fallback_adc; + spec->adc_nids = spec->private_adc_nids; + if (fallback_adc != fallback_cap) { + spec->private_capsrc_nids[0] = fallback_cap; + spec->capsrc_nids = spec->private_adc_nids; + } + } +} + #ifdef CONFIG_SND_HDA_INPUT_BEEP #define set_beep_amp(spec, nid, idx, dir) \ ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) @@ -6321,6 +6427,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) } } +#define alc260_auto_init_input_src alc880_auto_init_input_src + /* * generic initialization of ADC, input mixers and output mixers */ @@ -6407,6 +6515,7 @@ static void alc260_auto_init(struct hda_codec *codec) struct alc_spec *spec = codec->spec; alc260_auto_init_multi_out(codec); alc260_auto_init_analog_input(codec); + alc260_auto_init_input_src(codec); if (spec->unsol_event) alc_inithook(codec); } @@ -6473,7 +6582,7 @@ static struct alc_config_preset alc260_presets[] = { .num_dacs = ARRAY_SIZE(alc260_dac_nids), .dac_nids = alc260_dac_nids, .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), - .adc_nids = alc260_adc_nids, + .adc_nids = alc260_dual_adc_nids, .num_channel_mode = ARRAY_SIZE(alc260_modes), .channel_mode = alc260_modes, .input_mux = &alc260_capture_source, @@ -8379,6 +8488,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), + { } /* end */ +}; + +static struct hda_verb alc883_medion_wim2160_verbs[] = { + /* Unmute front mixer */ + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + /* Set speaker pin to front mixer */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + + /* Init headphone pin */ + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + + { } /* end */ +}; + +/* toggle speaker-output according to the hp-jack state */ +static void alc883_medion_wim2160_setup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + + spec->autocfg.hp_pins[0] = 0x1a; + spec->autocfg.speaker_pins[0] = 0x15; +} + static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -8393,9 +8538,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -9090,6 +9233,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", [ALC883_MEDION] = "medion", [ALC883_MEDION_MD2] = "medion-md2", + [ALC883_MEDION_WIM2160] = "medion-wim2160", [ALC883_LAPTOP_EAPD] = "laptop-eapd", [ALC883_LENOVO_101E_2ch] = "lenovo-101e", [ALC883_LENOVO_NB0763] = "lenovo-nb0763", @@ -9191,6 +9335,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), + SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), @@ -9200,10 +9345,12 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), @@ -9231,7 +9378,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), - SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), + SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG), {} }; @@ -9742,6 +9889,21 @@ static struct alc_config_preset alc882_presets[] = { .setup = alc883_medion_md2_setup, .init_hook = alc_automute_amp, }, + [ALC883_MEDION_WIM2160] = { + .mixers = { alc883_medion_wim2160_mixer }, + .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .dig_out_nid = ALC883_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), + .adc_nids = alc883_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), + .channel_mode = alc883_3ST_2ch_modes, + .input_mux = &alc883_capture_source, + .unsol_event = alc_automute_amp_unsol_event, + .setup = alc883_medion_wim2160_setup, + .init_hook = alc_automute_amp, + }, [ALC883_LAPTOP_EAPD] = { .mixers = { alc883_base_mixer }, .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, @@ -10034,6 +10196,8 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, int idx; alc_set_pin_output(codec, nid, pin_type); + if (dac_idx >= spec->multiout.num_dacs) + return; if (spec->multiout.dac_nids[dac_idx] == 0x25) idx = 4; else @@ -10105,6 +10269,8 @@ static void alc882_auto_init_input_src(struct hda_codec *codec) continue; mux_idx = c >= spec->num_mux_defs ? 0 : c; imux = &spec->input_mux[mux_idx]; + if (!imux->num_items && mux_idx > 0) + imux = &spec->input_mux[0]; for (idx = 0; idx < conns; idx++) { /* if the current connection is the selected one, * unmute it as default - otherwise mute it @@ -10283,7 +10449,8 @@ static int patch_alc882(struct hda_codec *codec) board_config = ALC882_AUTO; } - alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups); + if (board_config == ALC882_AUTO) + alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); if (board_config == ALC882_AUTO) { /* automatic parse from the BIOS config */ @@ -10356,6 +10523,9 @@ static int patch_alc882(struct hda_codec *codec) set_capture_mixer(codec); set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); + if (board_config == ALC882_AUTO) + alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); + spec->vmaster_nid = 0x0c; codec->patch_ops = alc_patch_ops; @@ -12447,11 +12617,11 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) unsigned char bits; present = snd_hda_jack_detect(codec, 0x15); - bits = present ? AMP_IN_MUTE(0) : 0; + bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); } static void alc268_acer_lc_unsol_event(struct hda_codec *codec, @@ -12736,6 +12906,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, dac = 0x02; break; case 0x15: + case 0x21: /* ALC269vb has this pin, too */ dac = 0x03; break; default: @@ -13201,7 +13372,7 @@ static int patch_alc268(struct hda_codec *codec) if (board_config < 0 || board_config >= ALC268_MODEL_LAST) board_config = snd_hda_check_board_codec_sid_config(codec, - ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); + ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", @@ -13321,9 +13492,9 @@ static hda_nid_t alc269vb_capsrc_nids[1] = { 0x22, }; -/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), - * not a mux! - */ +static hda_nid_t alc269_adc_candidates[] = { + 0x08, 0x09, 0x07, +}; #define alc269_modes alc260_modes #define alc269_capture_source alc880_lg_lw_capture_source @@ -13470,11 +13641,11 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) unsigned char bits; present = snd_hda_jack_detect(codec, 0x15); - bits = present ? AMP_IN_MUTE(0) : 0; + bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x0c); @@ -13499,11 +13670,11 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec) /* Check port replicator headphone socket */ present |= snd_hda_jack_detect(codec, 0x1a); - bits = present ? AMP_IN_MUTE(0) : 0; + bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x0c); @@ -13634,11 +13805,11 @@ static void alc269_speaker_automute(struct hda_codec *codec) unsigned char bits; present = snd_hda_jack_detect(codec, nid); - bits = present ? AMP_IN_MUTE(0) : 0; + bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); } /* unsolicited event for HP jack sensing */ @@ -13655,19 +13826,19 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec, } } -static void alc269_laptop_dmic_setup(struct hda_codec *codec) +static void alc269_laptop_amic_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; - spec->int_mic.pin = 0x12; - spec->int_mic.mux_idx = 5; + spec->int_mic.pin = 0x19; + spec->int_mic.mux_idx = 1; spec->auto_mic = 1; } -static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) +static void alc269_laptop_dmic_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x15; @@ -13675,14 +13846,14 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x12; - spec->int_mic.mux_idx = 6; + spec->int_mic.mux_idx = 5; spec->auto_mic = 1; } -static void alc269_laptop_amic_setup(struct hda_codec *codec) +static void alc269vb_laptop_amic_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - spec->autocfg.hp_pins[0] = 0x15; + spec->autocfg.hp_pins[0] = 0x21; spec->autocfg.speaker_pins[0] = 0x14; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; @@ -13691,6 +13862,18 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec) spec->auto_mic = 1; } +static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x21; + spec->autocfg.speaker_pins[0] = 0x14; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x12; + spec->int_mic.mux_idx = 6; + spec->auto_mic = 1; +} + static void alc269_laptop_inithook(struct hda_codec *codec) { alc269_speaker_automute(codec); @@ -13830,7 +14013,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int err; static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; - hda_nid_t real_capsrc_nids; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc269_ignore); @@ -13854,18 +14036,19 @@ static int alc269_parse_auto_config(struct hda_codec *codec) if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { add_verb(spec, alc269vb_init_verbs); - real_capsrc_nids = alc269vb_capsrc_nids[0]; alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); } else { add_verb(spec, alc269_init_verbs); - real_capsrc_nids = alc269_capsrc_nids[0]; alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); } spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux[0]; + fillup_priv_adc_nids(codec, alc269_adc_candidates, + sizeof(alc269_adc_candidates)); + /* set default input source */ - snd_hda_codec_write_cache(codec, real_capsrc_nids, + snd_hda_codec_write_cache(codec, spec->capsrc_nids[0], 0, AC_VERB_SET_CONNECT_SEL, spec->input_mux->items[0].index); @@ -13895,6 +14078,27 @@ static void alc269_auto_init(struct hda_codec *codec) alc_inithook(codec); } +enum { + ALC269_FIXUP_SONY_VAIO, +}; + +const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = { + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, + {} +}; + +static const struct alc_fixup alc269_fixups[] = { + [ALC269_FIXUP_SONY_VAIO] = { + .verbs = alc269_sony_vaio_fixup_verbs + }, +}; + +static struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), + {} +}; + + /* * configuration and preset */ @@ -13954,7 +14158,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { ALC269_DMIC), SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), - SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC), + SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), @@ -14028,7 +14232,7 @@ static struct alc_config_preset alc269_presets[] = { .num_channel_mode = ARRAY_SIZE(alc269_modes), .channel_mode = alc269_modes, .unsol_event = alc269_laptop_unsol_event, - .setup = alc269_laptop_amic_setup, + .setup = alc269vb_laptop_amic_setup, .init_hook = alc269_laptop_inithook, }, [ALC269VB_DMIC] = { @@ -14108,6 +14312,9 @@ static int patch_alc269(struct hda_codec *codec) board_config = ALC269_AUTO; } + if (board_config == ALC269_AUTO) + alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); + if (board_config == ALC269_AUTO) { /* automatic parse from the BIOS config */ err = alc269_parse_auto_config(codec); @@ -14144,20 +14351,25 @@ static int patch_alc269(struct hda_codec *codec) spec->stream_digital_playback = &alc269_pcm_digital_playback; spec->stream_digital_capture = &alc269_pcm_digital_capture; - if (!is_alc269vb) { - spec->adc_nids = alc269_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); - spec->capsrc_nids = alc269_capsrc_nids; - } else { - spec->adc_nids = alc269vb_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); - spec->capsrc_nids = alc269vb_capsrc_nids; + if (!spec->adc_nids) { /* wasn't filled automatically? use default */ + if (!is_alc269vb) { + spec->adc_nids = alc269_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); + spec->capsrc_nids = alc269_capsrc_nids; + } else { + spec->adc_nids = alc269vb_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); + spec->capsrc_nids = alc269vb_capsrc_nids; + } } if (!spec->cap_mixer) set_capture_mixer(codec); set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); + if (board_config == ALC269_AUTO) + alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); + spec->vmaster_nid = 0x02; codec->patch_ops = alc_patch_ops; @@ -15246,7 +15458,8 @@ static int patch_alc861(struct hda_codec *codec) board_config = ALC861_AUTO; } - alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups); + if (board_config == ALC861_AUTO) + alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); if (board_config == ALC861_AUTO) { /* automatic parse from the BIOS config */ @@ -15283,6 +15496,9 @@ static int patch_alc861(struct hda_codec *codec) spec->vmaster_nid = 0x03; + if (board_config == ALC861_AUTO) + alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); + codec->patch_ops = alc_patch_ops; if (board_config == ALC861_AUTO) { spec->init_hook = alc861_auto_init; @@ -16217,7 +16433,8 @@ static int patch_alc861vd(struct hda_codec *codec) board_config = ALC861VD_AUTO; } - alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups); + if (board_config == ALC861VD_AUTO) + alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); if (board_config == ALC861VD_AUTO) { /* automatic parse from the BIOS config */ @@ -16265,6 +16482,9 @@ static int patch_alc861vd(struct hda_codec *codec) spec->vmaster_nid = 0x02; + if (board_config == ALC861VD_AUTO) + alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); + codec->patch_ops = alc_patch_ops; if (board_config == ALC861VD_AUTO) @@ -17103,9 +17323,9 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec) present = snd_hda_jack_detect(codec, 0x21); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); } static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) @@ -17116,13 +17336,13 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) present = snd_hda_jack_detect(codec, 0x21); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); } static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) @@ -17133,13 +17353,13 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) present = snd_hda_jack_detect(codec, 0x15); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + HDA_AMP_MUTE, bits); } static void alc662_f5z_speaker_automute(struct hda_codec *codec) @@ -17178,14 +17398,14 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) if (present1 || present2) { snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), AMP_IN_MUTE(0)); + HDA_AMP_MUTE, HDA_AMP_MUTE); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), AMP_IN_MUTE(0)); + HDA_AMP_MUTE, HDA_AMP_MUTE); } else { snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), 0); + HDA_AMP_MUTE, 0); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), 0); + HDA_AMP_MUTE, 0); } } @@ -17651,7 +17871,6 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { ALC662_3ST_6ch_DIG), SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", ALC663_ASUS_H13), - SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG), {} }; diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 8c416bb18a57..a0e06d82da1f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -104,6 +104,7 @@ enum { STAC_DELL_M4_2, STAC_DELL_M4_3, STAC_HP_M4, + STAC_HP_DV4, STAC_HP_DV5, STAC_HP_HDX, STAC_HP_DV4_1222NR, @@ -1544,11 +1545,9 @@ static unsigned int alienware_m17x_pin_configs[13] = { 0x904601b0, }; -static unsigned int intel_dg45id_pin_configs[14] = { +static unsigned int intel_dg45id_pin_configs[13] = { 0x02214230, 0x02A19240, 0x01013214, 0x01014210, - 0x01A19250, 0x01011212, 0x01016211, 0x40f000f0, - 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x014510A0, - 0x074510B0, 0x40f000f0 + 0x01A19250, 0x01011212, 0x01016211 }; static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { @@ -1607,6 +1606,10 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { "Dell Studio 1555", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd, "Dell Studio 1557", STAC_DELL_M6_DMIC), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe, + "Dell Studio XPS 1645", STAC_DELL_M6_BOTH), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, + "Dell Studio 1558", STAC_DELL_M6_BOTH), {} /* terminator */ }; @@ -1689,6 +1692,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { [STAC_DELL_M4_2] = dell_m4_2_pin_configs, [STAC_DELL_M4_3] = dell_m4_3_pin_configs, [STAC_HP_M4] = NULL, + [STAC_HP_DV4] = NULL, [STAC_HP_DV5] = NULL, [STAC_HP_HDX] = NULL, [STAC_HP_DV4_1222NR] = NULL, @@ -1701,6 +1705,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { [STAC_DELL_M4_2] = "dell-m4-2", [STAC_DELL_M4_3] = "dell-m4-3", [STAC_HP_M4] = "hp-m4", + [STAC_HP_DV4] = "hp-dv4", [STAC_HP_DV5] = "hp-dv5", [STAC_HP_HDX] = "hp-hdx", [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", @@ -1719,7 +1724,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, "HP", STAC_HP_DV5), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, - "HP dv4-7", STAC_HP_DV5), + "HP dv4-7", STAC_HP_DV4), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, "HP dv4-7", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610, @@ -1730,6 +1735,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { "HP HDX", STAC_HP_HDX), /* HDX16 */ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3620, "HP dv6", STAC_HP_DV5), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3061, + "HP dv6", STAC_HP_DV5), /* HP dv6-1110ax */ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010, "HP", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, @@ -4762,6 +4769,9 @@ static void set_hp_led_gpio(struct hda_codec *codec) struct sigmatel_spec *spec = codec->spec; unsigned int gpio; + if (spec->gpio_led) + return; + gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); gpio &= AC_GPIO_IO_COUNT; if (gpio > 3) @@ -5671,6 +5681,9 @@ again: spec->num_smuxes = 1; spec->num_dmuxes = 1; /* fallthrough */ + case STAC_HP_DV4: + spec->gpio_led = 0x01; + /* fallthrough */ case STAC_HP_DV5: snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); @@ -5684,6 +5697,7 @@ again: spec->num_dmics = 1; spec->num_dmuxes = 1; spec->num_smuxes = 1; + spec->gpio_led = 0x08; break; } @@ -5740,7 +5754,8 @@ again: } /* enable bass on HP dv7 */ - if (spec->board_config == STAC_HP_DV5) { + if (spec->board_config == STAC_HP_DV4 || + spec->board_config == STAC_HP_DV5) { unsigned int cap; cap = snd_hda_param_read(codec, 0x1, AC_PAR_GPIO_CAP); cap &= AC_GPIO_IO_COUNT; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 9ddc37300f6b..73453814e098 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -476,7 +476,7 @@ static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, knew->name = kstrdup(tmpl->name, GFP_KERNEL); if (!knew->name) return NULL; - return 0; + return knew; } static void via_free_kctls(struct hda_codec *codec) @@ -1215,14 +1215,13 @@ static struct snd_kcontrol_new via_hp_mixer[2] = { }, }; -static int via_hp_build(struct via_spec *spec) +static int via_hp_build(struct hda_codec *codec) { + struct via_spec *spec = codec->spec; struct snd_kcontrol_new *knew; hda_nid_t nid; - - knew = via_clone_control(spec, &via_hp_mixer[0]); - if (knew == NULL) - return -ENOMEM; + int nums; + hda_nid_t conn[HDA_MAX_CONNECTIONS]; switch (spec->codec_type) { case VT1718S: @@ -1239,6 +1238,14 @@ static int via_hp_build(struct via_spec *spec) break; } + nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); + if (nums <= 1) + return 0; + + knew = via_clone_control(spec, &via_hp_mixer[0]); + if (knew == NULL) + return -ENOMEM; + knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; knew->private_value = nid; @@ -2561,7 +2568,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); return 1; @@ -3087,7 +3094,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); return 1; @@ -3654,7 +3661,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); return 1; @@ -4140,7 +4147,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); return 1; @@ -4510,7 +4517,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); return 1; } @@ -4930,7 +4937,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); @@ -5425,7 +5432,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); via_smart51_build(spec); @@ -5781,7 +5788,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); return 1; } @@ -6000,12 +6007,12 @@ static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec, /* Line-Out: PortE */ err = via_add_control(spec, VIA_CTL_WIDGET_VOL, - "Master Front Playback Volume", + "Front Playback Volume", HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT)); if (err < 0) return err; err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, - "Master Front Playback Switch", + "Front Playback Switch", HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT)); if (err < 0) return err; @@ -6130,7 +6137,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; if (spec->hp_mux) - via_hp_build(spec); + via_hp_build(codec); return 1; } diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c index 03391da8c8c7..90d560c3df13 100644 --- a/sound/pci/ice1712/ak4xxx.c +++ b/sound/pci/ice1712/ak4xxx.c @@ -24,6 +24,7 @@ #include <asm/io.h> #include <linux/delay.h> #include <linux/interrupt.h> +#include <linux/slab.h> #include <linux/init.h> #include <sound/core.h> #include <sound/initval.h> diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c index 6da21a2bcade..e328cfb7620c 100644 --- a/sound/pci/ice1712/amp.c +++ b/sound/pci/ice1712/amp.c @@ -25,7 +25,6 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/init.h> -#include <linux/slab.h> #include <sound/core.h> #include "ice1712.h" diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 9e66f6d306f8..2f6252266a02 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -1956,11 +1956,10 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) return 0; } - /* - * initialize the chip + * reset the chip */ -static int __devinit aureon_init(struct snd_ice1712 *ice) +static int aureon_reset(struct snd_ice1712 *ice) { static const unsigned short wm_inits_aureon[] = { /* These come first to reduce init pop noise */ @@ -2047,30 +2046,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */ (unsigned short)-1 }; - struct aureon_spec *spec; unsigned int tmp; const unsigned short *p; - int err, i; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (!spec) - return -ENOMEM; - ice->spec = spec; - - if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) { - ice->num_total_dacs = 6; - ice->num_total_adcs = 2; - } else { - /* aureon 7.1 and prodigy 7.1 */ - ice->num_total_dacs = 8; - ice->num_total_adcs = 2; - } - - /* to remeber the register values of CS8415 */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (!ice->akm) - return -ENOMEM; - ice->akm_codecs = 1; + int err; + struct aureon_spec *spec = ice->spec; err = aureon_ac97_init(ice); if (err != 0) @@ -2118,6 +2097,61 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) /* initialize PCA9554 pin directions & set default input */ aureon_pca9554_write(ice, PCA9554_DIR, 0x00); aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ + return 0; +} + +/* + * suspend/resume + */ +#ifdef CONFIG_PM +static int aureon_resume(struct snd_ice1712 *ice) +{ + struct aureon_spec *spec = ice->spec; + int err, i; + + err = aureon_reset(ice); + if (err != 0) + return err; + + /* workaround for poking volume with alsamixer after resume: + * just set stored volume again */ + for (i = 0; i < ice->num_total_dacs; i++) + wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); + return 0; +} +#endif + +/* + * initialize the chip + */ +static int __devinit aureon_init(struct snd_ice1712 *ice) +{ + struct aureon_spec *spec; + int i, err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return -ENOMEM; + ice->spec = spec; + + if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) { + ice->num_total_dacs = 6; + ice->num_total_adcs = 2; + } else { + /* aureon 7.1 and prodigy 7.1 */ + ice->num_total_dacs = 8; + ice->num_total_adcs = 2; + } + + /* to remeber the register values of CS8415 */ + ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + if (!ice->akm) + return -ENOMEM; + ice->akm_codecs = 1; + + err = aureon_reset(ice); + if (err != 0) + return err; spec->master[0] = WM_VOL_MUTE; spec->master[1] = WM_VOL_MUTE; @@ -2126,6 +2160,11 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]); } +#ifdef CONFIG_PM + ice->pm_resume = aureon_resume; + ice->pm_suspend_enabled = 1; +#endif + return 0; } diff --git a/sound/pci/ice1712/maya44.c b/sound/pci/ice1712/maya44.c index 3e1c20ae2f1c..726fd4b92e19 100644 --- a/sound/pci/ice1712/maya44.c +++ b/sound/pci/ice1712/maya44.c @@ -347,7 +347,7 @@ static int maya_gpio_sw_put(struct snd_kcontrol *kcontrol, /* known working input slots (0-4) */ #define MAYA_LINE_IN 1 /* in-2 */ -#define MAYA_MIC_IN 4 /* in-5 */ +#define MAYA_MIC_IN 3 /* in-4 */ static void wm8776_select_input(struct snd_maya44 *chip, int idx, int line) { @@ -393,8 +393,8 @@ static int maya_rec_src_put(struct snd_kcontrol *kcontrol, int changed; mutex_lock(&chip->mutex); - changed = maya_set_gpio_bits(chip->ice, GPIO_MIC_RELAY, - sel ? GPIO_MIC_RELAY : 0); + changed = maya_set_gpio_bits(chip->ice, 1 << GPIO_MIC_RELAY, + sel ? (1 << GPIO_MIC_RELAY) : 0); wm8776_select_input(chip, 0, sel ? MAYA_MIC_IN : MAYA_LINE_IN); mutex_unlock(&chip->mutex); return changed; diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c index 7f9674b641c0..4c551e147c08 100644 --- a/sound/pci/ice1712/vt1720_mobo.c +++ b/sound/pci/ice1712/vt1720_mobo.c @@ -25,7 +25,6 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/init.h> -#include <linux/slab.h> #include <sound/core.h> #include "ice1712.h" diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c index 5af9e84456d1..e618f789026e 100644 --- a/sound/pci/ice1712/wtm.c +++ b/sound/pci/ice1712/wtm.c @@ -29,7 +29,6 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/init.h> -#include <linux/slab.h> #include <sound/core.h> #include "ice1712.h" diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index 0cca56038cd9..ef9af3f4ace2 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c @@ -26,6 +26,7 @@ #include <linux/init.h> #include <linux/pci.h> #include <linux/delay.h> +#include <linux/slab.h> #include <sound/initval.h> #include <sound/control.h> diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index b64e78139d63..b56e33676780 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -849,6 +849,7 @@ struct snd_m3 { struct snd_kcontrol *master_switch; struct snd_kcontrol *master_volume; struct tasklet_struct hwvol_tq; + unsigned int in_suspend; #ifdef CONFIG_PM u16 *suspend_mem; @@ -884,6 +885,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = { MODULE_DEVICE_TABLE(pci, snd_m3_ids); static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = { + SND_PCI_QUIRK(0x0E11, 0x0094, "Compaq Evo N600c", 0x0c), SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d), SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d), SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03), @@ -1613,6 +1615,11 @@ static void snd_m3_update_hw_volume(unsigned long private_data) outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER); outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER); + /* Ignore spurious HV interrupts during suspend / resume, this avoids + mistaking them for a mute button press. */ + if (chip->in_suspend) + return; + if (!chip->master_switch || !chip->master_volume) return; @@ -2424,6 +2431,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state) if (chip->suspend_mem == NULL) return 0; + chip->in_suspend = 1; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_pcm_suspend_all(chip->pcm); snd_ac97_suspend(chip->ac97); @@ -2497,6 +2505,7 @@ static int m3_resume(struct pci_dev *pci) snd_m3_hv_init(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D0); + chip->in_suspend = 0; return 0; } #endif /* CONFIG_PM */ diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 7e8e7da592a9..6c3fd4d1c49d 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -27,6 +27,7 @@ #include <linux/dma-mapping.h> #include <linux/moduleparam.h> #include <linux/mutex.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/initval.h> @@ -1101,73 +1102,19 @@ static int snd_mixart_free(struct mixart_mgr *mgr) /* * proc interface */ -static long long snd_mixart_BA0_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - long long offset, - int orig) -{ - offset = offset & ~3; /* 4 bytes aligned */ - - switch(orig) { - case SEEK_SET: - file->f_pos = offset; - break; - case SEEK_CUR: - file->f_pos += offset; - break; - case SEEK_END: /* offset is negative */ - file->f_pos = MIXART_BA0_SIZE + offset; - break; - default: - return -EINVAL; - } - if(file->f_pos > MIXART_BA0_SIZE) - file->f_pos = MIXART_BA0_SIZE; - return file->f_pos; -} - -static long long snd_mixart_BA1_llseek(struct snd_info_entry *entry, - void *private_file_data, - struct file *file, - long long offset, - int orig) -{ - offset = offset & ~3; /* 4 bytes aligned */ - - switch(orig) { - case SEEK_SET: - file->f_pos = offset; - break; - case SEEK_CUR: - file->f_pos += offset; - break; - case SEEK_END: /* offset is negative */ - file->f_pos = MIXART_BA1_SIZE + offset; - break; - default: - return -EINVAL; - } - if(file->f_pos > MIXART_BA1_SIZE) - file->f_pos = MIXART_BA1_SIZE; - return file->f_pos; -} /* mixart_BA0 proc interface for BAR 0 - read callback */ -static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_mixart_BA0_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { struct mixart_mgr *mgr = entry->private_data; count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ - if(count <= 0) - return 0; - if(pos + count > MIXART_BA0_SIZE) - count = (long)(MIXART_BA0_SIZE - pos); - if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count)) + if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count)) return -EFAULT; return count; } @@ -1175,30 +1122,25 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private /* mixart_BA1 proc interface for BAR 1 - read callback */ -static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private_data, - struct file *file, char __user *buf, - unsigned long count, unsigned long pos) +static ssize_t snd_mixart_BA1_read(struct snd_info_entry *entry, + void *file_private_data, + struct file *file, char __user *buf, + size_t count, loff_t pos) { struct mixart_mgr *mgr = entry->private_data; count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ - if(count <= 0) - return 0; - if(pos + count > MIXART_BA1_SIZE) - count = (long)(MIXART_BA1_SIZE - pos); - if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count)) + if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count)) return -EFAULT; return count; } static struct snd_info_entry_ops snd_mixart_proc_ops_BA0 = { .read = snd_mixart_BA0_read, - .llseek = snd_mixart_BA0_llseek }; static struct snd_info_entry_ops snd_mixart_proc_ops_BA1 = { .read = snd_mixart_BA1_read, - .llseek = snd_mixart_BA1_llseek }; diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index 4cf4cd8c939c..bf2696aa5d49 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c @@ -24,6 +24,7 @@ #include <linux/pci.h> #include <linux/firmware.h> #include <linux/vmalloc.h> +#include <linux/slab.h> #include <asm/io.h> #include <sound/core.h> #include "mixart.h" diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 9c5e6450eebb..fad03d64e3ad 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -21,6 +21,7 @@ #include <linux/interrupt.h> #include <linux/mutex.h> #include <linux/pci.h> +#include <linux/slab.h> #include <sound/ac97_codec.h> #include <sound/asoundef.h> #include <sound/core.h> diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index 16c226bfcd2b..7c4986b27f2b 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -56,6 +56,7 @@ #include <sound/pcm_params.h> #include <sound/tlv.h> #include "xonar.h" +#include "cm9780.h" #include "cs4398.h" #include "cs4362a.h" @@ -172,6 +173,8 @@ static void xonar_d1_init(struct oxygen *chip) oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); + oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); + xonar_init_cs53x1(chip); xonar_enable_output(chip); diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index d5e1c6eb7b7b..3c04524de37c 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -70,10 +70,10 @@ #include <linux/delay.h> +#include <linux/gfp.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <sound/core.h> diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 9d5252bc870c..d19dc052c391 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -27,7 +27,6 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <sound/core.h> diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 52c6eb57cc3f..b92adef8e81e 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -24,7 +24,6 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/interrupt.h> -#include <linux/slab.h> #include <linux/pci.h> #include <linux/firmware.h> #include <linux/moduleparam.h> diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 3d72c1effeef..547b713d7204 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -2479,7 +2479,7 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol, on MADICARD - playback mixer matrix: [channelout+64] [output] [value] - input(thru) mixer matrix: [channelin] [output] [value] - (better do 2 kontrols for seperation ?) + (better do 2 kontrols for separation ?) */ #define HDSPM_MIXER(xname, xindex) \ diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 44a3e2d8c556..c492af5b25f3 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -24,7 +24,6 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/slab.h> #include <linux/moduleparam.h> #include <sound/core.h> diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index 7e3e8fbc90fe..9cc1b5aa0148 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c @@ -24,6 +24,7 @@ #include <linux/init.h> #include <linux/pci.h> #include <linux/time.h> +#include <linux/slab.h> #include <linux/moduleparam.h> #include <linux/interrupt.h> #include <linux/delay.h> diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c index 5d2afa0b0ce4..9dce0bde5c05 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c @@ -19,6 +19,7 @@ */ #include <linux/delay.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/info.h> #include "pdaudiocf.h" diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c index 0d668f471620..43f995a3f960 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c @@ -20,7 +20,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <linux/slab.h> #include <linux/delay.h> #include <sound/core.h> #include <sound/asoundef.h> diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 7be3b3357045..cfd1438bcc64 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/moduleparam.h> +#include <linux/slab.h> #include <sound/core.h> #include "vxpocket.h" #include <pcmcia/ciscode.h> diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c index 1f72e1c786bf..00e2d5166d0a 100644 --- a/sound/ppc/burgundy.c +++ b/sound/ppc/burgundy.c @@ -21,7 +21,6 @@ #include <asm/io.h> #include <linux/init.h> -#include <linux/slab.h> #include <linux/delay.h> #include <sound/core.h> #include "pmac.h" diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c index d06f780bd7e8..8f064c7ce745 100644 --- a/sound/ppc/keywest.c +++ b/sound/ppc/keywest.c @@ -22,7 +22,6 @@ #include <linux/init.h> #include <linux/i2c.h> #include <linux/delay.h> -#include <linux/slab.h> #include <sound/core.h> #include "pmac.h" diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index 53c81a547613..2f12da4da561 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c @@ -20,10 +20,10 @@ #include <linux/dma-mapping.h> #include <linux/dmapool.h> +#include <linux/gfp.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> -#include <linux/slab.h> #include <sound/asound.h> #include <sound/control.h> diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 789f44f4ac78..20afdf9772ee 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c @@ -30,6 +30,7 @@ #include <linux/kmod.h> #include <linux/slab.h> #include <linux/interrupt.h> +#include <linux/string.h> #include <sound/core.h> #include <asm/io.h> #include <asm/irq.h> @@ -46,6 +47,8 @@ #define DBG(fmt...) #endif +#define IS_G4DA (of_machine_is_compatible("PowerMac3,4")) + /* i2c address for tumbler */ #define TAS_I2C_ADDR 0x34 @@ -243,6 +246,7 @@ static int tumbler_set_master_volume(struct pmac_tumbler *mix) snd_printk(KERN_ERR "failed to set volume \n"); return -EINVAL; } + DBG("(I) succeeded to set volume (%u, %u)\n", left_vol, right_vol); return 0; } @@ -353,6 +357,7 @@ static int tumbler_set_drc(struct pmac_tumbler *mix) snd_printk(KERN_ERR "failed to set DRC\n"); return -EINVAL; } + DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]); return 0; } @@ -389,6 +394,7 @@ static int snapper_set_drc(struct pmac_tumbler *mix) snd_printk(KERN_ERR "failed to set DRC\n"); return -EINVAL; } + DBG("(I) succeeded to set DRC (%u, %u)\n", val[0], val[1]); return 0; } @@ -1134,7 +1140,8 @@ static long tumbler_find_device(const char *device, const char *platform, gp->inactive_val = (*base) ? 0x4 : 0x5; } else { const u32 *prop = NULL; - gp->active_state = 0; + gp->active_state = IS_G4DA + && !strncmp(device, "keywest-gpio1", 13); gp->active_val = 0x4; gp->inactive_val = 0x5; /* Here are some crude hacks to extract the GPIO polarity and @@ -1312,6 +1319,9 @@ static int __devinit tumbler_init(struct snd_pmac *chip) if (irq <= NO_IRQ) irq = tumbler_find_device("line-output-detect", NULL, &mix->line_detect, 1); + if (IS_G4DA && irq <= NO_IRQ) + irq = tumbler_find_device("keywest-gpio16", + NULL, &mix->line_detect, 1); mix->lineout_irq = irq; tumbler_reset_audio(chip); diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c index 76d9ad27d91c..68e0dee4ff05 100644 --- a/sound/sh/sh_dac_audio.c +++ b/sound/sh/sh_dac_audio.c @@ -26,6 +26,7 @@ #include <linux/interrupt.h> #include <linux/io.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/initval.h> #include <sound/pcm.h> diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c index 9ef6b96373f5..3e6628c8e665 100644 --- a/sound/soc/atmel/atmel-pcm.c +++ b/sound/soc/atmel/atmel-pcm.c @@ -180,7 +180,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = params_buffer_bytes(params); - prtd->params = rtd->dai->cpu_dai->dma_data; + prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); prtd->params->dma_intr_handler = atmel_pcm_dma_irq; prtd->dma_buffer = runtime->dma_addr; diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index e588e63f18d2..0b59806905d1 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -363,12 +363,12 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, ssc_p->dma_params[dir] = dma_params; /* - * The cpu_dai->dma_data field is only used to communicate the - * appropriate DMA parameters to the pcm driver hw_params() + * The snd_soc_pcm_stream->dma_data field is only used to communicate + * the appropriate DMA parameters to the pcm driver hw_params() * function. It should not be used for other purposes * as it is common to all substreams. */ - rtd->dai->cpu_dai->dma_data = dma_params; + snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params); channels = params_channels(params); diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 340311d7fed5..a61ccd2d505f 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -17,6 +17,7 @@ #include <linux/init.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/device.h> #include <linux/delay.h> #include <linux/mutex.h> diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index 0cf2ca61c776..495be6e71931 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/suspend.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index 67cbfe7283da..5e7aacf3bb5a 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c @@ -29,8 +29,8 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/slab.h> #include <linux/dma-mapping.h> +#include <linux/gfp.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index e69322978739..523b7fc33f4e 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c @@ -16,6 +16,7 @@ #include <linux/interrupt.h> #include <linux/wait.h> #include <linux/delay.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index c6c6a4a7d948..1d2a1adf2575 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -29,8 +29,8 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/slab.h> #include <linux/dma-mapping.h> +#include <linux/gfp.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c index 5e03bb2f3cd7..6bac1ac1a315 100644 --- a/sound/soc/blackfin/bf5xx-tdm-pcm.c +++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c @@ -29,8 +29,8 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/slab.h> #include <linux/dma-mapping.h> +#include <linux/gfp.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index a1bbe16b7f96..1f5e57a4bb7a 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -13,6 +13,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/kernel.h> #include <linux/device.h> #include <sound/core.h> @@ -80,9 +81,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, static int ac97_soc_probe(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_card *card = socdev->card; struct snd_soc_codec *codec; struct snd_ac97_bus *ac97_bus; struct snd_ac97_template ac97_template; + int i; int ret = 0; printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); @@ -102,12 +105,6 @@ static int ac97_soc_probe(struct platform_device *pdev) INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); - ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); - if (ret < 0) { - printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n"); - goto err; - } - /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) @@ -123,6 +120,13 @@ static int ac97_soc_probe(struct platform_device *pdev) if (ret < 0) goto bus_err; + for (i = 0; i < card->num_links; i++) { + if (card->dai_link[i].codec_dai->ac97_control) { + snd_ac97_dev_add_pdata(codec->ac97, + card->dai_link[i].cpu_dai->ac97_pdata); + } + } + return 0; bus_err: diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 3c80137d5938..11b62dee842c 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -17,6 +17,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c index c233810d463d..240cd155b313 100644 --- a/sound/soc/codecs/ad1938.c +++ b/sound/soc/codecs/ad1938.c @@ -27,6 +27,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 39c0f7584e65..042072738cdc 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -12,6 +12,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index d2fcc601722c..475807bea2c2 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c @@ -11,6 +11,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c index cc96411ca3e6..f8e75edb27b7 100644 --- a/sound/soc/codecs/ads117x.c +++ b/sound/soc/codecs/ads117x.c @@ -11,6 +11,7 @@ */ #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/init.h> #include <linux/device.h> #include <sound/core.h> diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index b68d99fb6af0..bdeb10dfd887 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c @@ -10,6 +10,7 @@ */ #include <linux/module.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/soc.h> #include <sound/initval.h> diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index ff966567e2ba..352d1d08dbd9 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -19,6 +19,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 3ef16bbc8c83..729859cf6ca8 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -29,6 +29,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 82fca284d007..926797a014c7 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/i2c.h> #include <linux/delay.h> +#include <linux/slab.h> #include <sound/soc.h> #include <sound/soc-dapm.h> #include <sound/initval.h> diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index dfbeb2db61b3..81a62d198b70 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -23,6 +23,7 @@ #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/soc.h> #include <sound/initval.h> diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index e000cdfec1ec..9f169c477108 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -14,6 +14,7 @@ */ #include <linux/tty.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/initval.h> diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index cf2975a7294a..366daf1d044e 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -23,6 +23,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index 2afcd0a8669d..5a5f187a2657 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <linux/device.h> #include <linux/gpio.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/initval.h> diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index d2ff1cde6883..29d0906a924a 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -33,6 +33,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 81b8c9dfe7fc..3293629dcb3b 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -15,6 +15,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/device.h> #include <sound/core.h> diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index da589d8664d0..776b79cde904 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -25,6 +25,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 357b609196e3..b5b7d6a03844 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -13,6 +13,7 @@ #include <linux/device.h> #include <linux/sysfs.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index e4b946a19ea3..4a6d56c3fed9 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -39,6 +39,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index f9f367d29a90..d1e0e81ef30c 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -31,6 +31,7 @@ #include <linux/interrupt.h> #include <linux/gpio.h> #include <linux/regulator/consumer.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -778,7 +779,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) if (dac33->fifo_mode) { /* Generic for all FIFO modes */ /* 50-51 : ASRC Control registers */ - dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */ + dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCLKDIV(1)); dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */ /* Write registers 0x34 and 0x35 (MSB, LSB) */ @@ -1038,11 +1039,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai, case SND_SOC_DAIFMT_DSP_A: aictrl_a |= DAC33_AFMT_DSP; aictrl_b &= ~DAC33_DATA_DELAY_MASK; - aictrl_b |= DAC33_DATA_DELAY(1); /* 1 bit delay */ - break; - case SND_SOC_DAIFMT_DSP_B: - aictrl_a |= DAC33_AFMT_DSP; - aictrl_b &= ~DAC33_DATA_DELAY_MASK; /* No delay */ + aictrl_b |= DAC33_DATA_DELAY(0); break; case SND_SOC_DAIFMT_RIGHT_J: aictrl_a |= DAC33_AFMT_RIGHT_J; @@ -1066,7 +1063,7 @@ static void dac33_init_chip(struct snd_soc_codec *codec) { /* 44-46: DAC Control Registers */ /* A : DAC sample rate Fsref/1.5 */ - dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(1)); + dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0)); /* B : DAC src=normal, not muted */ dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT | DAC33_DACSRCL_LEFT); diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 958d49c969ac..569ad8758a84 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -26,6 +26,7 @@ #include <linux/i2c.h> #include <linux/gpio.h> #include <linux/regulator/consumer.h> +#include <linux/slab.h> #include <sound/tpa6130a2-plat.h> #include <sound/soc.h> #include <sound/soc-dapm.h> diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 6f5d4af20052..520ffd6536c3 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -27,6 +27,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/i2c/twl.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 3e99fe5131dd..a8dcd5a5bbcb 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/delay.h> +#include <linux/slab.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 217b02680597..002e289d1255 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -23,7 +23,6 @@ #include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/version.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/firmware.h> @@ -32,6 +31,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/debugfs.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index df2c6d9617fb..2e0772f9c456 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> +#include <linux/slab.h> #include <linux/delay.h> #include <linux/pm.h> #include <linux/platform_device.h> diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index b432f4d4a324..6acc885cf9b7 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/init.h> #include <linux/delay.h> #include <linux/pm.h> diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index af8cb6995a1f..9000b1d19afb 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -19,6 +19,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index d3a61d7ea0c5..19cd47293424 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -19,6 +19,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index d077df6f5e75..8cc9042965eb 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -25,6 +25,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 24a35603bcf7..8ca3812f2f2f 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -20,6 +20,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index 63a254e293ca..1072621e93fd 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c @@ -13,6 +13,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 3fb653ba363a..07adc375a706 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -18,6 +18,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 5a2619dbf283..e7c6bf163185 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> +#include <linux/slab.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 475c67ac7818..2916ed4d3844 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -20,6 +20,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index c2444e7c8480..613199a0f799 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -40,6 +40,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 44e7d9d82f87..60b1b3e1094b 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -20,6 +20,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index dbc368c08263..b7fd96adac64 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -24,6 +24,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 3595bd57c4eb..fa5f99fde68b 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -23,6 +23,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 593e47d0e0eb..c6f0abcc5711 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -19,6 +19,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 31e39ffd1d8e..0c04b476487f 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -30,6 +30,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 615dab2b62ef..c8d7a809af4d 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -18,6 +18,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index d07bcc1e1c60..f1e63e01b04d 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -15,6 +15,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index d2342c5e0425..50634ab76a5c 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -18,6 +18,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index d9540d55fc89..a65b781af512 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -20,6 +20,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index ee637af4737a..69708c4cc004 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -18,6 +18,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 28bb59ea6ea1..526f56b09066 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -19,6 +19,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 2862e4dced27..bb18c3ecfeb9 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -19,6 +19,7 @@ #include <linux/i2c.h> #include <linux/spi/spi.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index a54dc77b7f34..831f4730bfd5 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -18,6 +18,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -990,7 +991,7 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, reg = snd_soc_read(codec, WM8990_CLOCKING_2); snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC); - /* set up N , fractional mode and pre-divisor if neccessary */ + /* set up N , fractional mode and pre-divisor if necessary */ snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM | (pll_div.div2?WM8990_PRESCALE:0)); snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8)); diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index bf022f68b84f..03e8b1a6a56c 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -18,6 +18,7 @@ #include <linux/i2c.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 29f3771c33a4..9da0724cd47a 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -19,6 +19,7 @@ #include <linux/i2c.h> #include <linux/platform_device.h> #include <linux/regulator/consumer.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -3007,34 +3008,39 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_OFF: - /* Switch over to startup biases */ - snd_soc_update_bits(codec, WM8994_ANTIPOP_2, - WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | - WM8994_VMID_BUF_ENA | - WM8994_VMID_RAMP_MASK, - WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | - WM8994_VMID_BUF_ENA | - (1 << WM8994_VMID_RAMP_SHIFT)); - - /* Disable main biases */ - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, - WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0); + if (codec->bias_level == SND_SOC_BIAS_STANDBY) { + /* Switch over to startup biases */ + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM8994_BIAS_SRC | + WM8994_STARTUP_BIAS_ENA | + WM8994_VMID_BUF_ENA | + WM8994_VMID_RAMP_MASK, + WM8994_BIAS_SRC | + WM8994_STARTUP_BIAS_ENA | + WM8994_VMID_BUF_ENA | + (1 << WM8994_VMID_RAMP_SHIFT)); - /* Discharge line */ - snd_soc_update_bits(codec, WM8994_ANTIPOP_1, - WM8994_LINEOUT1_DISCH | - WM8994_LINEOUT2_DISCH, - WM8994_LINEOUT1_DISCH | - WM8994_LINEOUT2_DISCH); + /* Disable main biases */ + snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, + WM8994_BIAS_ENA | + WM8994_VMID_SEL_MASK, 0); - msleep(5); + /* Discharge line */ + snd_soc_update_bits(codec, WM8994_ANTIPOP_1, + WM8994_LINEOUT1_DISCH | + WM8994_LINEOUT2_DISCH, + WM8994_LINEOUT1_DISCH | + WM8994_LINEOUT2_DISCH); - /* Switch off startup biases */ - snd_soc_update_bits(codec, WM8994_ANTIPOP_2, - WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | - WM8994_VMID_BUF_ENA | - WM8994_VMID_RAMP_MASK, 0); + msleep(5); + /* Switch off startup biases */ + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM8994_BIAS_SRC | + WM8994_STARTUP_BIAS_ENA | + WM8994_VMID_BUF_ENA | + WM8994_VMID_RAMP_MASK, 0); + } break; } codec->bias_level = level; @@ -3401,7 +3407,7 @@ struct snd_soc_dai wm8994_dai[] = { .rates = WM8994_RATES, .formats = WM8994_FORMATS, }, - .playback = { + .capture = { .stream_name = "AIF3 Capture", .channels_min = 2, .channels_max = 2, @@ -3730,11 +3736,12 @@ static int wm8994_codec_probe(struct platform_device *pdev) case 3: wm8994->hubs.dcs_codes = -5; wm8994->hubs.hp_startup_mode = 1; + wm8994->hubs.dcs_readback_mode = 1; break; default: + wm8994->hubs.dcs_readback_mode = 1; break; } - /* Remember if AIFnLRCLK is configured as a GPIO. This should be * configured on init - if a system wants to do this dynamically diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index c468497314ba..3a184fcb702b 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -18,6 +18,7 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index ec54c6da9856..8793341849d1 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -10,6 +10,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index e237bf615129..2f48a8aae22c 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -11,6 +11,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/device.h> diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index ceb86b4ddb25..2fca514fde58 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -16,6 +16,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/device.h> #include <sound/core.h> diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 0ad9f5d536c6..e1f225a3ac46 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -62,21 +62,27 @@ static const char *speaker_mode_text[] = { static const struct soc_enum speaker_mode = SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text); -static void wait_for_dc_servo(struct snd_soc_codec *codec) +static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op) { unsigned int reg; int count = 0; + unsigned int val; + + val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1; + + /* Trigger the command */ + snd_soc_write(codec, WM8993_DC_SERVO_0, val); dev_dbg(codec->dev, "Waiting for DC servo...\n"); do { count++; msleep(1); - reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0); + reg = snd_soc_read(codec, WM8993_DC_SERVO_0); dev_dbg(codec->dev, "DC servo: %x\n", reg); - } while (reg & WM8993_DCS_DATAPATH_BUSY); + } while (reg & op && count < 400); - if (reg & WM8993_DCS_DATAPATH_BUSY) + if (reg & op) dev_err(codec->dev, "Timed out waiting for DC Servo\n"); } @@ -86,51 +92,58 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec) static void calibrate_dc_servo(struct snd_soc_codec *codec) { struct wm_hubs_data *hubs = codec->private_data; - u16 reg, dcs_cfg; + u16 reg, reg_l, reg_r, dcs_cfg; /* Set for 32 series updates */ snd_soc_update_bits(codec, WM8993_DC_SERVO_1, WM8993_DCS_SERIES_NO_01_MASK, 32 << WM8993_DCS_SERIES_NO_01_SHIFT); - - /* Enable the DC servo. Write all bits to avoid triggering startup - * or write calibration. - */ - snd_soc_update_bits(codec, WM8993_DC_SERVO_0, - 0xFFFF, - WM8993_DCS_ENA_CHAN_0 | - WM8993_DCS_ENA_CHAN_1 | - WM8993_DCS_TRIG_SERIES_1 | - WM8993_DCS_TRIG_SERIES_0); - - wait_for_dc_servo(codec); + wait_for_dc_servo(codec, + WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1); /* Apply correction to DC servo result */ if (hubs->dcs_codes) { dev_dbg(codec->dev, "Applying %d code DC servo correction\n", hubs->dcs_codes); + /* Different chips in the family support different + * readback methods. + */ + switch (hubs->dcs_readback_mode) { + case 0: + reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) + & WM8993_DCS_INTEG_CHAN_0_MASK;; + reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) + & WM8993_DCS_INTEG_CHAN_1_MASK; + break; + case 1: + reg = snd_soc_read(codec, WM8993_DC_SERVO_3); + reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) + >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; + reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; + break; + default: + WARN(1, "Unknown DCS readback method"); + break; + } + /* HPOUT1L */ - reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) & - WM8993_DCS_INTEG_CHAN_0_MASK;; - reg += hubs->dcs_codes; - dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT; + if (reg_l + hubs->dcs_codes > 0 && + reg_l + hubs->dcs_codes < 0xff) + reg_l += hubs->dcs_codes; + dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT; /* HPOUT1R */ - reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) & - WM8993_DCS_INTEG_CHAN_1_MASK; - reg += hubs->dcs_codes; - dcs_cfg |= reg; + if (reg_r + hubs->dcs_codes > 0 && + reg_r + hubs->dcs_codes < 0xff) + reg_r += hubs->dcs_codes; + dcs_cfg |= reg_r; /* Do it */ snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); - snd_soc_update_bits(codec, WM8993_DC_SERVO_0, - WM8993_DCS_TRIG_DAC_WR_0 | - WM8993_DCS_TRIG_DAC_WR_1, - WM8993_DCS_TRIG_DAC_WR_0 | - WM8993_DCS_TRIG_DAC_WR_1); - - wait_for_dc_servo(codec); + wait_for_dc_servo(codec, + WM8993_DCS_TRIG_DAC_WR_0 | + WM8993_DCS_TRIG_DAC_WR_1); } } @@ -141,10 +154,16 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm_hubs_data *hubs = codec->private_data; int ret; ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); + /* If we're applying an offset correction then updating the + * callibration would be likely to introduce further offsets. */ + if (hubs->dcs_codes) + return ret; + /* Only need to do this if the outputs are active */ if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1) & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA)) diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index 420104fe9c90..e51c16683589 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h @@ -21,6 +21,7 @@ extern const unsigned int wm_hubs_spkmix_tlv[]; /* This *must* be the first element of the codec->private_data struct */ struct wm_hubs_data { int dcs_codes; + int dcs_readback_mode; int hp_startup_mode; }; diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index 6362ca05506e..adadcd3aa1b1 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/device.h> +#include <linux/slab.h> #include <linux/delay.h> #include <linux/io.h> #include <linux/clk.h> @@ -585,7 +586,8 @@ static int davinci_i2s_probe(struct platform_device *pdev) dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; davinci_i2s_dai.private_data = dev; - davinci_i2s_dai.dma_data = dev->dma_params; + davinci_i2s_dai.capture.dma_data = dev->dma_params; + davinci_i2s_dai.playback.dma_data = dev->dma_params; ret = snd_soc_register_dai(&davinci_i2s_dai); if (ret != 0) goto err_free_mem; diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index ab6518d86f18..79f0f4ad242c 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/device.h> +#include <linux/slab.h> #include <linux/delay.h> #include <linux/io.h> #include <linux/clk.h> @@ -917,7 +918,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dma_data->channel = res->start; davinci_mcasp_dai[pdata->op_mode].private_data = dev; - davinci_mcasp_dai[pdata->op_mode].dma_data = dev->dma_params; + davinci_mcasp_dai[pdata->op_mode].capture.dma_data = dev->dma_params; + davinci_mcasp_dai[pdata->op_mode].playback.dma_data = dev->dma_params; davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 80c7fdf2f521..2dc406f42fe7 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -649,8 +649,10 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_hardware *ppcm; int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->dma_data; + struct davinci_pcm_dma_params *pa; struct davinci_pcm_dma_params *params; + + pa = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); if (!pa) return -ENODEV; params = &pa[substream->stream]; diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index b1a3a278819f..410c7496a18d 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -19,6 +19,7 @@ #include <linux/dma-mapping.h> #include <linux/interrupt.h> #include <linux/delay.h> +#include <linux/gfp.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 93f0f38a32c9..762c1b8e8e4e 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -14,6 +14,7 @@ #include <linux/interrupt.h> #include <linux/device.h> #include <linux/delay.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index 30ed568afb2e..d639e55c5124 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -8,6 +8,7 @@ #include <linux/module.h> #include <linux/of_device.h> +#include <linux/slab.h> #include <sound/soc.h> diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index ef67d1cdffe7..83de1c81c8c4 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -9,6 +9,7 @@ * express or implied. */ +#include <linux/slab.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/of_device.h> diff --git a/sound/soc/fsl/soc-of-simple.c b/sound/soc/fsl/soc-of-simple.c index 8bc5cd9e972f..3bc13fd89096 100644 --- a/sound/soc/fsl/soc-of-simple.c +++ b/sound/soc/fsl/soc-of-simple.c @@ -12,6 +12,7 @@ #include <linux/bitops.h> #include <linux/platform_device.h> #include <linux/of.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index c7d0fd9b7de8..7174b4c710de 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig @@ -1,6 +1,6 @@ config SND_IMX_SOC tristate "SoC Audio for Freescale i.MX CPUs" - depends on ARCH_MXC && BROKEN + depends on ARCH_MXC select SND_PCM select FIQ select SND_SOC_AC97_BUS diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 19452e44afdc..2b31ac673ea4 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -19,6 +19,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/initval.h> @@ -70,7 +71,12 @@ static void imx_ssi_dma_callback(int channel, void *data) static void snd_imx_dma_err_callback(int channel, void *data, int err) { - pr_err("DMA error callback called\n"); + struct snd_pcm_substream *substream = data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct imx_pcm_runtime_data *iprtd = runtime->private_data; + int ret; pr_err("DMA timeout on channel %d -%s%s%s%s\n", channel, @@ -78,16 +84,26 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) err & IMX_DMA_ERR_REQUEST ? " request" : "", err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); + + imx_dma_disable(iprtd->dma); + ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, + IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, + substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + DMA_MODE_WRITE : DMA_MODE_READ); + if (!ret) + imx_dma_enable(iprtd->dma); } static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; + struct imx_pcm_dma_params *dma_params; struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; int ret; + dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); + iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); if (iprtd->dma < 0) { pr_err("Failed to claim the audio DMA\n"); @@ -192,10 +208,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; + struct imx_pcm_dma_params *dma_params; struct imx_pcm_runtime_data *iprtd = runtime->private_data; int err; + dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); + iprtd->substream = substream; iprtd->buf = (unsigned int *)substream->dma_buffer.area; iprtd->period_cnt = 0; diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c index d9cb9849b033..6b518e07eea9 100644 --- a/sound/soc/imx/imx-pcm-fiq.c +++ b/sound/soc/imx/imx-pcm-fiq.c @@ -19,6 +19,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/initval.h> @@ -38,23 +39,24 @@ struct imx_pcm_runtime_data { unsigned long offset; unsigned long last_offset; unsigned long size; - struct timer_list timer; - int poll_time; + struct hrtimer hrt; + int poll_time_ns; + struct snd_pcm_substream *substream; + atomic_t running; }; -static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd) +static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) { - iprtd->timer.expires = jiffies + iprtd->poll_time; -} - -static void imx_ssi_timer_callback(unsigned long data) -{ - struct snd_pcm_substream *substream = (void *)data; + struct imx_pcm_runtime_data *iprtd = + container_of(hrt, struct imx_pcm_runtime_data, hrt); + struct snd_pcm_substream *substream = iprtd->substream; struct snd_pcm_runtime *runtime = substream->runtime; - struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct pt_regs regs; unsigned long delta; + if (!atomic_read(&iprtd->running)) + return HRTIMER_NORESTART; + get_fiq_regs(®s); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -71,16 +73,14 @@ static void imx_ssi_timer_callback(unsigned long data) /* If we've transferred at least a period then report it and * reset our poll time */ - if (delta >= runtime->period_size) { + if (delta >= iprtd->period) { snd_pcm_period_elapsed(substream); iprtd->last_offset = iprtd->offset; - - imx_ssi_set_next_poll(iprtd); } - /* Restart the timer; if we didn't report we'll run on the next tick */ - add_timer(&iprtd->timer); + hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns)); + return HRTIMER_RESTART; } static struct fiq_handler fh = { @@ -98,8 +98,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, iprtd->period = params_period_bytes(params) ; iprtd->offset = 0; iprtd->last_offset = 0; - iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params)); - + iprtd->poll_time_ns = 1000000000 / params_rate(params) * + params_period_size(params); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); return 0; @@ -134,8 +134,9 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - imx_ssi_set_next_poll(iprtd); - add_timer(&iprtd->timer); + atomic_set(&iprtd->running, 1); + hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns), + HRTIMER_MODE_REL); if (++fiq_enable == 1) enable_fiq(imx_pcm_fiq); @@ -144,11 +145,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - del_timer(&iprtd->timer); + atomic_set(&iprtd->running, 0); + if (--fiq_enable == 0) disable_fiq(imx_pcm_fiq); - break; default: return -EINVAL; @@ -179,7 +180,7 @@ static struct snd_pcm_hardware snd_imx_hardware = { .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, .period_bytes_min = 128, .period_bytes_max = 16 * 1024, - .periods_min = 2, + .periods_min = 4, .periods_max = 255, .fifo_size = 0, }; @@ -193,9 +194,11 @@ static int snd_imx_open(struct snd_pcm_substream *substream) iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); runtime->private_data = iprtd; - init_timer(&iprtd->timer); - iprtd->timer.data = (unsigned long)substream; - iprtd->timer.function = imx_ssi_timer_callback; + iprtd->substream = substream; + + atomic_set(&iprtd->running, 0); + hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + iprtd->hrt.function = snd_hrtimer_callback; ret = snd_pcm_hw_constraint_integer(substream->runtime, SNDRV_PCM_HW_PARAM_PERIODS); @@ -211,7 +214,8 @@ static int snd_imx_close(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct imx_pcm_runtime_data *iprtd = runtime->private_data; - del_timer_sync(&iprtd->timer); + hrtimer_cancel(&iprtd->hrt); + kfree(iprtd); return 0; diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 56f46a75d297..80b4fee2442b 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -39,6 +39,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/initval.h> @@ -234,17 +235,20 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct imx_ssi *ssi = cpu_dai->private_data; + struct imx_pcm_dma_params *dma_data; u32 reg, sccr; /* Tx/Rx config */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { reg = SSI_STCCR; - cpu_dai->dma_data = &ssi->dma_params_tx; + dma_data = &ssi->dma_params_tx; } else { reg = SSI_SRCCR; - cpu_dai->dma_data = &ssi->dma_params_rx; + dma_data = &ssi->dma_params_rx; } + snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); + sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; /* DAI data (word) size */ @@ -652,7 +656,8 @@ static int imx_ssi_probe(struct platform_device *pdev) dai->private_data = ssi; if ((cpu_is_mx27() || cpu_is_mx21()) && - !(ssi->flags & IMX_SSI_USE_AC97)) { + !(ssi->flags & IMX_SSI_USE_AC97) && + (ssi->flags & IMX_SSI_DMA)) { ssi->flags |= IMX_SSI_DMA; platform = imx_ssi_dma_mx2_init(pdev, ssi); } else diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c index ad8df6cfae88..1dab4c14874d 100644 --- a/sound/soc/omap/mcpdm.c +++ b/sound/soc/omap/mcpdm.c @@ -25,6 +25,7 @@ #include <linux/device.h> #include <linux/platform_device.h> #include <linux/wait.h> +#include <linux/slab.h> #include <linux/interrupt.h> #include <linux/err.h> #include <linux/clk.h> diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index e814a9591f78..8ad9dc901007 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -297,7 +297,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode; omap_mcbsp_dai_dma_params[id][substream->stream].data_type = OMAP_DMA_DATA_TYPE_S16; - cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; + + snd_soc_dai_set_dma_data(cpu_dai, substream, + &omap_mcbsp_dai_dma_params[id][substream->stream]); if (mcbsp_data->configured) { /* McBSP already configured by another stream */ diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 25f19e4728bf..b7f4f7e015f3 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -150,7 +150,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, int stream = substream->stream; int channels, err, link_mask = 0; - cpu_dai->dma_data = &omap_mcpdm_dai_dma_params[stream]; + snd_soc_dai_set_dma_data(cpu_dai, substream, + &omap_mcpdm_dai_dma_params[stream]); channels = params_channels(params); switch (channels) { diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 825db385f01f..1e521904ea64 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -23,6 +23,7 @@ */ #include <linux/dma-mapping.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -60,12 +61,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data) struct omap_runtime_data *prtd = runtime->private_data; unsigned long flags; - if ((cpu_is_omap1510()) && - (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) { + if ((cpu_is_omap1510())) { /* * OMAP1510 doesn't fully support DMA progress counter * and there is no software emulation implemented yet, - * so have to maintain our own playback progress counter + * so have to maintain our own progress counters * that can be used by omap_pcm_pointer() instead. */ spin_lock_irqsave(&prtd->lock, flags); @@ -100,9 +100,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct omap_runtime_data *prtd = runtime->private_data; - struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data; + struct omap_pcm_dma_data *dma_data; int err = 0; + dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); + /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ if (!dma_data) @@ -189,8 +191,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) dma_params.frame_count = runtime->periods; omap_set_dma_params(prtd->dma_ch, &dma_params); - if ((cpu_is_omap1510()) && - (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) + if ((cpu_is_omap1510())) omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); else @@ -248,14 +249,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) dma_addr_t ptr; snd_pcm_uframes_t offset; - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (cpu_is_omap1510()) { + offset = prtd->period_index * runtime->period_size; + } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { ptr = omap_get_dma_dst_pos(prtd->dma_ch); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); - } else if (!(cpu_is_omap1510())) { + } else { ptr = omap_get_dma_src_pos(prtd->dma_ch); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); - } else - offset = prtd->period_index * runtime->period_size; + } if (offset >= runtime->buffer_size) offset = 0; diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index e69397f40f72..544fd9566f4d 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -16,6 +16,7 @@ #include <linux/init.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/platform_device.h> #include <linux/clk.h> #include <linux/io.h> @@ -42,11 +43,14 @@ * SSP audio private data */ struct ssp_priv { - struct ssp_dev dev; + struct ssp_device *ssp; unsigned int sysclk; int dai_fmt; #ifdef CONFIG_PM - struct ssp_state state; + uint32_t cr0; + uint32_t cr1; + uint32_t to; + uint32_t psp; #endif }; @@ -61,6 +65,22 @@ static void dump_registers(struct ssp_device *ssp) ssp_read_reg(ssp, SSACD)); } +static void ssp_enable(struct ssp_device *ssp) +{ + uint32_t sscr0; + + sscr0 = __raw_readl(ssp->mmio_base + SSCR0) | SSCR0_SSE; + __raw_writel(sscr0, ssp->mmio_base + SSCR0); +} + +static void ssp_disable(struct ssp_device *ssp) +{ + uint32_t sscr0; + + sscr0 = __raw_readl(ssp->mmio_base + SSCR0) & ~SSCR0_SSE; + __raw_writel(sscr0, ssp->mmio_base + SSCR0); +} + struct pxa2xx_pcm_dma_data { struct pxa2xx_pcm_dma_params params; char name[20]; @@ -94,19 +114,17 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct ssp_priv *priv = cpu_dai->private_data; + struct ssp_device *ssp = priv->ssp; int ret = 0; if (!cpu_dai->active) { - priv->dev.port = cpu_dai->id + 1; - priv->dev.irq = NO_IRQ; - clk_enable(priv->dev.ssp->clk); - ssp_disable(&priv->dev); + clk_enable(ssp->clk); + ssp_disable(ssp); } - if (cpu_dai->dma_data) { - kfree(cpu_dai->dma_data); - cpu_dai->dma_data = NULL; - } + kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); + snd_soc_dai_set_dma_data(cpu_dai, substream, NULL); + return ret; } @@ -116,16 +134,15 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct ssp_priv *priv = cpu_dai->private_data; + struct ssp_device *ssp = priv->ssp; if (!cpu_dai->active) { - ssp_disable(&priv->dev); - clk_disable(priv->dev.ssp->clk); + ssp_disable(ssp); + clk_disable(ssp->clk); } - if (cpu_dai->dma_data) { - kfree(cpu_dai->dma_data); - cpu_dai->dma_data = NULL; - } + kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); + snd_soc_dai_set_dma_data(cpu_dai, substream, NULL); } #ifdef CONFIG_PM @@ -133,27 +150,39 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai) { struct ssp_priv *priv = cpu_dai->private_data; + struct ssp_device *ssp = priv->ssp; if (!cpu_dai->active) - clk_enable(priv->dev.ssp->clk); + clk_enable(ssp->clk); - ssp_save_state(&priv->dev, &priv->state); - clk_disable(priv->dev.ssp->clk); + priv->cr0 = __raw_readl(ssp->mmio_base + SSCR0); + priv->cr1 = __raw_readl(ssp->mmio_base + SSCR1); + priv->to = __raw_readl(ssp->mmio_base + SSTO); + priv->psp = __raw_readl(ssp->mmio_base + SSPSP); + ssp_disable(ssp); + clk_disable(ssp->clk); return 0; } static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai) { struct ssp_priv *priv = cpu_dai->private_data; + struct ssp_device *ssp = priv->ssp; + uint32_t sssr = SSSR_ROR | SSSR_TUR | SSSR_BCE; - clk_enable(priv->dev.ssp->clk); - ssp_restore_state(&priv->dev, &priv->state); + clk_enable(ssp->clk); + + __raw_writel(sssr, ssp->mmio_base + SSSR); + __raw_writel(priv->cr0 & ~SSCR0_SSE, ssp->mmio_base + SSCR0); + __raw_writel(priv->cr1, ssp->mmio_base + SSCR1); + __raw_writel(priv->to, ssp->mmio_base + SSTO); + __raw_writel(priv->psp, ssp->mmio_base + SSPSP); if (cpu_dai->active) - ssp_enable(&priv->dev); + ssp_enable(ssp); else - clk_disable(priv->dev.ssp->clk); + clk_disable(ssp->clk); return 0; } @@ -203,7 +232,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { struct ssp_priv *priv = cpu_dai->private_data; - struct ssp_device *ssp = priv->dev.ssp; + struct ssp_device *ssp = priv->ssp; int val; u32 sscr0 = ssp_read_reg(ssp, SSCR0) & @@ -244,11 +273,11 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, /* The SSP clock must be disabled when changing SSP clock mode * on PXA2xx. On PXA3xx it must be enabled when doing so. */ if (!cpu_is_pxa3xx()) - clk_disable(priv->dev.ssp->clk); + clk_disable(ssp->clk); val = ssp_read_reg(ssp, SSCR0) | sscr0; ssp_write_reg(ssp, SSCR0, val); if (!cpu_is_pxa3xx()) - clk_enable(priv->dev.ssp->clk); + clk_enable(ssp->clk); return 0; } @@ -260,7 +289,7 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, int div_id, int div) { struct ssp_priv *priv = cpu_dai->private_data; - struct ssp_device *ssp = priv->dev.ssp; + struct ssp_device *ssp = priv->ssp; int val; switch (div_id) { @@ -311,7 +340,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id, int source, unsigned int freq_in, unsigned int freq_out) { struct ssp_priv *priv = cpu_dai->private_data; - struct ssp_device *ssp = priv->dev.ssp; + struct ssp_device *ssp = priv->ssp; u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70; #if defined(CONFIG_PXA3xx) @@ -380,7 +409,7 @@ static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) { struct ssp_priv *priv = cpu_dai->private_data; - struct ssp_device *ssp = priv->dev.ssp; + struct ssp_device *ssp = priv->ssp; u32 sscr0; sscr0 = ssp_read_reg(ssp, SSCR0); @@ -415,7 +444,7 @@ static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai, int tristate) { struct ssp_priv *priv = cpu_dai->private_data; - struct ssp_device *ssp = priv->dev.ssp; + struct ssp_device *ssp = priv->ssp; u32 sscr1; sscr1 = ssp_read_reg(ssp, SSCR1); @@ -437,7 +466,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { struct ssp_priv *priv = cpu_dai->private_data; - struct ssp_device *ssp = priv->dev.ssp; + struct ssp_device *ssp = priv->ssp; u32 sscr0; u32 sscr1; u32 sspsp; @@ -532,25 +561,29 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct ssp_priv *priv = cpu_dai->private_data; - struct ssp_device *ssp = priv->dev.ssp; + struct ssp_device *ssp = priv->ssp; int chn = params_channels(params); u32 sscr0; u32 sspsp; int width = snd_pcm_format_physical_width(params_format(params)); int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; + struct pxa2xx_pcm_dma_params *dma_data; + + dma_data = snd_soc_dai_get_dma_data(dai, substream); /* generate correct DMA params */ - if (cpu_dai->dma_data) - kfree(cpu_dai->dma_data); + kfree(dma_data); /* Network mode with one active slot (ttsa == 1) can be used * to force 16-bit frame width on the wire (for S16_LE), even * with two channels. Use 16-bit DMA transfers for this case. */ - cpu_dai->dma_data = ssp_get_dma_params(ssp, + dma_data = ssp_get_dma_params(ssp, ((chn == 2) && (ttsa != 1)) || (width == 32), substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + snd_soc_dai_set_dma_data(dai, substream, dma_data); + /* we can only change the settings if the port is not in use */ if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) return 0; @@ -642,12 +675,12 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; int ret = 0; struct ssp_priv *priv = cpu_dai->private_data; - struct ssp_device *ssp = priv->dev.ssp; + struct ssp_device *ssp = priv->ssp; int val; switch (cmd) { case SNDRV_PCM_TRIGGER_RESUME: - ssp_enable(&priv->dev); + ssp_enable(ssp); break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: val = ssp_read_reg(ssp, SSCR1); @@ -666,7 +699,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, else val |= SSCR1_RSRE; ssp_write_reg(ssp, SSCR1, val); - ssp_enable(&priv->dev); + ssp_enable(ssp); break; case SNDRV_PCM_TRIGGER_STOP: val = ssp_read_reg(ssp, SSCR1); @@ -677,7 +710,7 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, ssp_write_reg(ssp, SSCR1, val); break; case SNDRV_PCM_TRIGGER_SUSPEND: - ssp_disable(&priv->dev); + ssp_disable(ssp); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: val = ssp_read_reg(ssp, SSCR1); @@ -707,8 +740,8 @@ static int pxa_ssp_probe(struct platform_device *pdev, if (!priv) return -ENOMEM; - priv->dev.ssp = ssp_request(dai->id + 1, "SoC audio"); - if (priv->dev.ssp == NULL) { + priv->ssp = ssp_request(dai->id + 1, "SoC audio"); + if (priv->ssp == NULL) { ret = -ENODEV; goto err_priv; } @@ -727,7 +760,7 @@ static void pxa_ssp_remove(struct platform_device *pdev, struct snd_soc_dai *dai) { struct ssp_priv *priv = dai->private_data; - ssp_free(priv->dev.ssp); + ssp_free(priv->ssp); } #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index e9ae7b3a7e00..d314115e3dd7 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -122,11 +122,14 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct pxa2xx_pcm_dma_params *dma_data; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out; + dma_data = &pxa2xx_ac97_pcm_stereo_out; else - cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_in; + dma_data = &pxa2xx_ac97_pcm_stereo_in; + + snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); return 0; } @@ -137,11 +140,14 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct pxa2xx_pcm_dma_params *dma_data; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out; + dma_data = &pxa2xx_ac97_pcm_aux_mono_out; else - cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_in; + dma_data = &pxa2xx_ac97_pcm_aux_mono_in; + + snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); return 0; } @@ -156,7 +162,8 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) return -ENODEV; else - cpu_dai->dma_data = &pxa2xx_ac97_pcm_mic_mono_in; + snd_soc_dai_set_dma_data(cpu_dai, substream, + &pxa2xx_ac97_pcm_mic_mono_in); return 0; } diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 6b8f655d1ad8..c1a5275721e4 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -164,6 +164,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct pxa2xx_pcm_dma_params *dma_data; BUG_ON(IS_ERR(clk_i2s)); clk_enable(clk_i2s); @@ -171,9 +172,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, pxa_i2s_wait(); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_out; + dma_data = &pxa2xx_i2s_pcm_stereo_out; else - cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_in; + dma_data = &pxa2xx_i2s_pcm_stereo_in; + + snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); /* is port used by another stream */ if (!(SACR0 & SACR0_ENB)) { diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index d38e39575f51..adc7e6f15f93 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c @@ -25,9 +25,11 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct pxa2xx_runtime_data *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; + struct pxa2xx_pcm_dma_params *dma; int ret; + dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); + /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ if (!dma) diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c index ee8ed9d7e703..ecf4fd04ae96 100644 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ b/sound/soc/s3c24xx/s3c-ac97.c @@ -224,11 +224,14 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct s3c_dma_params *dma_data; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - cpu_dai->dma_data = &s3c_ac97_pcm_out; + dma_data = &s3c_ac97_pcm_out; else - cpu_dai->dma_data = &s3c_ac97_pcm_in; + dma_data = &s3c_ac97_pcm_in; + + snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); return 0; } @@ -238,8 +241,8 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, { u32 ac_glbctrl; struct snd_soc_pcm_runtime *rtd = substream->private_data; - int channel = ((struct s3c_dma_params *) - rtd->dai->cpu_dai->dma_data)->channel; + struct s3c_dma_params *dma_data = + snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) @@ -265,7 +268,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); + s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); return 0; } @@ -280,7 +283,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) return -ENODEV; else - cpu_dai->dma_data = &s3c_ac97_mic_in; + snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in); return 0; } @@ -290,8 +293,8 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, { u32 ac_glbctrl; struct snd_soc_pcm_runtime *rtd = substream->private_data; - int channel = ((struct s3c_dma_params *) - rtd->dai->cpu_dai->dma_data)->channel; + struct s3c_dma_params *dma_data = + snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; @@ -311,7 +314,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); + s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); return 0; } diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/s3c24xx/s3c-dma.c index 7725e26d6c91..1b61c23ff300 100644 --- a/sound/soc/s3c24xx/s3c-dma.c +++ b/sound/soc/s3c24xx/s3c-dma.c @@ -145,10 +145,12 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct s3c24xx_runtime_data *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_dma_params *dma = rtd->dai->cpu_dai->dma_data; unsigned long totbytes = params_buffer_bytes(params); + struct s3c_dma_params *dma = + snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); int ret = 0; + pr_debug("Entered %s\n", __func__); /* return if this is a bufferless transfer e.g. diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index e994d8374fe6..88515946b6c0 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -339,14 +339,17 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai_link *dai = rtd->dai; struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); + struct s3c_dma_params *dma_data; u32 iismod; pr_debug("Entered %s\n", __func__); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dai->cpu_dai->dma_data = i2s->dma_playback; + dma_data = i2s->dma_playback; else - dai->cpu_dai->dma_data = i2s->dma_capture; + dma_data = i2s->dma_capture; + + snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data); /* Working copies of register */ iismod = readl(i2s->regs + S3C2412_IISMOD); @@ -394,8 +397,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); unsigned long irqs; int ret = 0; - int channel = ((struct s3c_dma_params *) - rtd->dai->cpu_dai->dma_data)->channel; + struct s3c_dma_params *dma_data = + snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); pr_debug("Entered %s\n", __func__); @@ -431,7 +434,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, * of the auto reload mechanism of S3C24XX. * This call won't bother S3C64XX. */ - s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); + s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); break; diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c index a98f40c3cd29..326f0a9e7e30 100644 --- a/sound/soc/s3c24xx/s3c-pcm.c +++ b/sound/soc/s3c24xx/s3c-pcm.c @@ -178,6 +178,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai_link *dai = rtd->dai; struct s3c_pcm_info *pcm = to_info(dai->cpu_dai); + struct s3c_dma_params *dma_data; void __iomem *regs = pcm->regs; struct clk *clk; int sclk_div, sync_div; @@ -187,9 +188,11 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, dev_dbg(pcm->dev, "Entered %s\n", __func__); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dai->cpu_dai->dma_data = pcm->dma_playback; + dma_data = pcm->dma_playback; else - dai->cpu_dai->dma_data = pcm->dma_capture; + dma_data = pcm->dma_capture; + + snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data); /* Strictly check for sample size */ switch (params_format(params)) { diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index 0bc5950b9f02..c3ac890a3986 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -242,14 +242,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_dma_params *dma_data; u32 iismod; pr_debug("Entered %s\n", __func__); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out; + dma_data = &s3c24xx_i2s_pcm_stereo_out; else - rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in; + dma_data = &s3c24xx_i2s_pcm_stereo_in; + + snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_data); /* Working copies of register */ iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); @@ -258,13 +261,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: iismod &= ~S3C2410_IISMOD_16BIT; - ((struct s3c_dma_params *) - rtd->dai->cpu_dai->dma_data)->dma_size = 1; + dma_data->dma_size = 1; break; case SNDRV_PCM_FORMAT_S16_LE: iismod |= S3C2410_IISMOD_16BIT; - ((struct s3c_dma_params *) - rtd->dai->cpu_dai->dma_data)->dma_size = 2; + dma_data->dma_size = 2; break; default: return -EINVAL; @@ -280,8 +281,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, { int ret = 0; struct snd_soc_pcm_runtime *rtd = substream->private_data; - int channel = ((struct s3c_dma_params *) - rtd->dai->cpu_dai->dma_data)->channel; + struct s3c_dma_params *dma_data = + snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); pr_debug("Entered %s\n", __func__); @@ -300,7 +301,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, else s3c24xx_snd_txctrl(1); - s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); + s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 93ed3aad1631..a72c251401ac 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -22,8 +22,8 @@ #include <sound/soc.h> #include <plat/regs-s3c2412-iis.h> -#include <plat/gpio-bank-d.h> -#include <plat/gpio-bank-e.h> +#include <mach/gpio-bank-d.h> +#include <mach/gpio-bank-e.h> #include <plat/gpio-cfg.h> #include <mach/map.h> diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index c5cda187ecab..5b9ac1759bd2 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c @@ -16,6 +16,7 @@ #include <linux/clk.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -518,7 +519,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev) s6000_i2s_dai.dev = &pdev->dev; s6000_i2s_dai.private_data = dev; - s6000_i2s_dai.dma_data = &dev->dma_params; + s6000_i2s_dai.capture.dma_data = &dev->dma_params; + s6000_i2s_dai.playback.dma_data = &dev->dma_params; dev->sifbase = sifmem->start; dev->scbbase = mmio; diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c index 1d61109e09fa..9c7f7f00cebb 100644 --- a/sound/soc/s6000/s6000-pcm.c +++ b/sound/soc/s6000/s6000-pcm.c @@ -58,13 +58,15 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct s6000_runtime_data *prtd = runtime->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *par; int channel; unsigned int period_size; unsigned int dma_offset; dma_addr_t dma_pos; dma_addr_t src, dst; + par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); + period_size = snd_pcm_lib_period_bytes(substream); dma_offset = prtd->period * period_size; dma_pos = runtime->dma_addr + dma_offset; @@ -101,7 +103,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data) { struct snd_pcm *pcm = data; struct snd_soc_pcm_runtime *runtime = pcm->private_data; - struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *params = + snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); struct s6000_runtime_data *prtd; unsigned int has_xrun; int i, ret = IRQ_NONE; @@ -172,11 +175,13 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream) { struct s6000_runtime_data *prtd = substream->runtime->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *par; unsigned long flags; int srcinc; u32 dma; + par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); + spin_lock_irqsave(&prtd->lock, flags); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { @@ -212,10 +217,12 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream) { struct s6000_runtime_data *prtd = substream->runtime->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *par; unsigned long flags; u32 channel; + par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) channel = par->dma_out; else @@ -236,9 +243,11 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream) static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *par; int ret; + par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); + ret = par->trigger(substream, cmd, 0); if (ret < 0) return ret; @@ -275,13 +284,15 @@ static int s6000_pcm_prepare(struct snd_pcm_substream *substream) static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *par; struct snd_pcm_runtime *runtime = substream->runtime; struct s6000_runtime_data *prtd = runtime->private_data; unsigned long flags; unsigned int offset; dma_addr_t count; + par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); + spin_lock_irqsave(&prtd->lock, flags); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -305,11 +316,12 @@ static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream) static int s6000_pcm_open(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *par; struct snd_pcm_runtime *runtime = substream->runtime; struct s6000_runtime_data *prtd; int ret; + par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware); ret = snd_pcm_hw_constraint_step(runtime, 0, @@ -364,7 +376,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *par; int ret; ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); @@ -373,6 +385,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, return ret; } + par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); + if (par->same_rate) { spin_lock(&par->lock); if (par->rate == -1 || @@ -392,7 +406,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, static int s6000_pcm_hw_free(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *par = + snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); spin_lock(&par->lock); par->in_use &= ~(1 << substream->stream); @@ -417,7 +432,8 @@ static struct snd_pcm_ops s6000_pcm_ops = { static void s6000_pcm_free(struct snd_pcm *pcm) { struct snd_soc_pcm_runtime *runtime = pcm->private_data; - struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *params = + snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); free_irq(params->irq, pcm); snd_pcm_lib_preallocate_free_for_all(pcm); @@ -429,9 +445,11 @@ static int s6000_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, struct snd_pcm *pcm) { struct snd_soc_pcm_runtime *runtime = pcm->private_data; - struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; + struct s6000_pcm_dma_params *params; int res; + params = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); + if (!card->dev->dma_mask) card->dev->dma_mask = &s6000_pcm_dmamask; if (!card->dev->coherent_dma_mask) diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index 106674979b53..f07f6d8b93e1 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig @@ -32,6 +32,7 @@ config SND_SOC_SH4_SIU select DMA_ENGINE select DMADEVICES select SH_DMAE + select FW_LOADER ## ## Boards diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index baddb1242c71..0d8bdf07729c 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c @@ -13,6 +13,7 @@ */ #include <linux/module.h> +#include <linux/gfp.h> #include <linux/init.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 993abb730dfa..8dc966f45c36 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -19,6 +19,7 @@ #include <linux/list.h> #include <linux/pm_runtime.h> #include <linux/io.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/initval.h> diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index 5452d19607e1..d86ee1bfc03a 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c @@ -22,6 +22,7 @@ #include <linux/delay.h> #include <linux/firmware.h> #include <linux/pm_runtime.h> +#include <linux/slab.h> #include <asm/clock.h> #include <asm/siu.h> diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index ba7f8d05d977..8f85719212f9 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -24,7 +24,6 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/platform_device.h> -#include <linux/slab.h> #include <sound/control.h> #include <sound/core.h> diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c8b0556ef431..ad7f9528d751 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -28,6 +28,7 @@ #include <linux/bitops.h> #include <linux/debugfs.h> #include <linux/platform_device.h> +#include <linux/slab.h> #include <sound/ac97_codec.h> #include <sound/core.h> #include <sound/pcm.h> @@ -1548,7 +1549,8 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) mutex_unlock(&codec->mutex); return ret; } - if (card->dai_link[i].codec_dai->ac97_control) { + /* Check for codec->ac97 to handle the ac97.c fun */ + if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) { snd_ac97_dev_add_pdata(codec->ac97, card->dai_link[i].cpu_dai->ac97_pdata); } diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 6c3351095786..7c28f401f436 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -38,6 +38,7 @@ #include <linux/platform_device.h> #include <linux/jiffies.h> #include <linux/debugfs.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index 0f83bdb9b16f..0ec20b68e8cb 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c @@ -16,6 +16,7 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/gfp.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> @@ -253,3 +254,4 @@ module_exit(txx9aclc_ac97_exit); MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); MODULE_DESCRIPTION("TXx9 ACLC AC97 driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:txx9aclc-ac97"); diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c index 3175de9a92cb..95b17f731aec 100644 --- a/sound/soc/txx9/txx9aclc-generic.c +++ b/sound/soc/txx9/txx9aclc-generic.c @@ -96,3 +96,4 @@ module_exit(txx9aclc_generic_exit); MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:txx9aclc-generic"); diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index efed64b8b026..49cc7ea9a518 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/scatterlist.h> +#include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/sound_firmware.c b/sound/sound_firmware.c index 96deaefaa897..340a0bc5303e 100644 --- a/sound/sound_firmware.c +++ b/sound/sound_firmware.c @@ -2,7 +2,6 @@ #include <linux/module.h> #include <linux/fs.h> #include <linux/mm.h> -#include <linux/slab.h> #include <linux/sched.h> #include <asm/uaccess.h> #include "oss/sound_firmware.h" diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 8d13d933087d..7dcc06512e86 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -10,7 +10,6 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/slab.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/interrupt.h> diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 1d2e51b3f918..2eab6ce48852 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -58,6 +58,7 @@ #include <linux/irq.h> #include <linux/io.h> #include <linux/dma-mapping.h> +#include <linux/gfp.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/synth/emux/emux_proc.c b/sound/synth/emux/emux_proc.c index 687e6a13689e..58a32a10d115 100644 --- a/sound/synth/emux/emux_proc.c +++ b/sound/synth/emux/emux_proc.c @@ -19,7 +19,6 @@ */ #include <linux/wait.h> -#include <linux/slab.h> #include <sound/core.h> #include <sound/emux_synth.h> #include <sound/info.h> diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index c570ae3e6d55..c4dcbadd83aa 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig @@ -65,6 +65,7 @@ config SND_USB_CAIAQ * Native Instruments Audio 8 DJ * Native Instruments Guitar Rig Session I/O * Native Instruments Guitar Rig mobile + * Native Instruments Traktor Kontrol X1 To compile this driver as a module, choose M here: the module will be called snd-usb-caiaq. diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 86b2c3b92df5..4328cad6c3a2 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c @@ -17,6 +17,7 @@ */ #include <linux/spinlock.h> +#include <linux/slab.h> #include <linux/init.h> #include <linux/usb.h> #include <sound/core.h> diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c index 537102ba6b9d..36ed703a7416 100644 --- a/sound/usb/caiaq/control.c +++ b/sound/usb/caiaq/control.c @@ -35,33 +35,41 @@ static int control_info(struct snd_kcontrol *kcontrol, struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); int pos = kcontrol->private_value; int is_intval = pos & CNT_INTVAL; - unsigned int id = dev->chip.usb_id; + int maxval = 63; uinfo->count = 1; pos &= ~CNT_INTVAL; - if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ) - && (pos == 0)) { - /* current input mode of A8DJ */ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 2; - return 0; - } + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): + if (pos == 0) { + /* current input mode of A8DJ */ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 2; + return 0; + } + break; - if (id == USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ) - && (pos == 0)) { - /* current input mode of A4DJ */ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): + if (pos == 0) { + /* current input mode of A4DJ */ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; + } + break; + + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): + maxval = 127; + break; } if (is_intval) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->value.integer.min = 0; - uinfo->value.integer.max = 64; + uinfo->value.integer.max = maxval; } else { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->value.integer.min = 0; @@ -102,9 +110,10 @@ static int control_put(struct snd_kcontrol *kcontrol, struct snd_usb_audio *chip = snd_kcontrol_chip(kcontrol); struct snd_usb_caiaqdev *dev = caiaqdev(chip->card); int pos = kcontrol->private_value; + unsigned char cmd = EP1_CMD_WRITE_IO; - if (dev->chip.usb_id == - USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ)) { + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): { /* A4DJ has only one control */ /* do not expose hardware input mode 0 */ dev->control_state[0] = ucontrol->value.integer.value[0] + 1; @@ -113,10 +122,15 @@ static int control_put(struct snd_kcontrol *kcontrol, return 1; } + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): + cmd = EP1_CMD_DIMM_LEDS; + break; + } + if (pos & CNT_INTVAL) { dev->control_state[pos & ~CNT_INTVAL] = ucontrol->value.integer.value[0]; - snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, + snd_usb_caiaq_send_command(dev, cmd, dev->control_state, sizeof(dev->control_state)); } else { if (ucontrol->value.integer.value[0]) @@ -124,7 +138,7 @@ static int control_put(struct snd_kcontrol *kcontrol, else dev->control_state[pos / 8] &= ~(1 << (pos % 8)); - snd_usb_caiaq_send_command(dev, EP1_CMD_WRITE_IO, + snd_usb_caiaq_send_command(dev, cmd, dev->control_state, sizeof(dev->control_state)); } @@ -273,6 +287,43 @@ static struct caiaq_controller a4dj_controller[] = { { "Current input mode", 0 | CNT_INTVAL } }; +static struct caiaq_controller kontrolx1_controller[] = { + { "LED FX A: ON", 7 | CNT_INTVAL }, + { "LED FX A: 1", 6 | CNT_INTVAL }, + { "LED FX A: 2", 5 | CNT_INTVAL }, + { "LED FX A: 3", 4 | CNT_INTVAL }, + { "LED FX B: ON", 3 | CNT_INTVAL }, + { "LED FX B: 1", 2 | CNT_INTVAL }, + { "LED FX B: 2", 1 | CNT_INTVAL }, + { "LED FX B: 3", 0 | CNT_INTVAL }, + + { "LED Hotcue", 28 | CNT_INTVAL }, + { "LED Shift (white)", 29 | CNT_INTVAL }, + { "LED Shift (green)", 30 | CNT_INTVAL }, + + { "LED Deck A: FX1", 24 | CNT_INTVAL }, + { "LED Deck A: FX2", 25 | CNT_INTVAL }, + { "LED Deck A: IN", 17 | CNT_INTVAL }, + { "LED Deck A: OUT", 16 | CNT_INTVAL }, + { "LED Deck A: < BEAT", 19 | CNT_INTVAL }, + { "LED Deck A: BEAT >", 18 | CNT_INTVAL }, + { "LED Deck A: CUE/ABS", 21 | CNT_INTVAL }, + { "LED Deck A: CUP/REL", 20 | CNT_INTVAL }, + { "LED Deck A: PLAY", 23 | CNT_INTVAL }, + { "LED Deck A: SYNC", 22 | CNT_INTVAL }, + + { "LED Deck B: FX1", 26 | CNT_INTVAL }, + { "LED Deck B: FX2", 27 | CNT_INTVAL }, + { "LED Deck B: IN", 15 | CNT_INTVAL }, + { "LED Deck B: OUT", 14 | CNT_INTVAL }, + { "LED Deck B: < BEAT", 13 | CNT_INTVAL }, + { "LED Deck B: BEAT >", 12 | CNT_INTVAL }, + { "LED Deck B: CUE/ABS", 11 | CNT_INTVAL }, + { "LED Deck B: CUP/REL", 10 | CNT_INTVAL }, + { "LED Deck B: PLAY", 9 | CNT_INTVAL }, + { "LED Deck B: SYNC", 8 | CNT_INTVAL }, +}; + static int __devinit add_controls(struct caiaq_controller *c, int num, struct snd_usb_caiaqdev *dev) { @@ -321,10 +372,16 @@ int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev) ret = add_controls(a8dj_controller, ARRAY_SIZE(a8dj_controller), dev); break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO4DJ): ret = add_controls(a4dj_controller, ARRAY_SIZE(a4dj_controller), dev); break; + + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): + ret = add_controls(kontrolx1_controller, + ARRAY_SIZE(kontrolx1_controller), dev); + break; } return ret; diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index a3f02dd97440..805271827675 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c @@ -23,6 +23,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/init.h> +#include <linux/gfp.h> #include <linux/usb.h> #include <sound/initval.h> #include <sound/core.h> @@ -46,7 +47,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," "{Native Instruments, Audio 4 DJ}," "{Native Instruments, Audio 8 DJ}," "{Native Instruments, Session I/O}," - "{Native Instruments, GuitarRig mobile}"); + "{Native Instruments, GuitarRig mobile}" + "{Native Instruments, Traktor Kontrol X1}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ @@ -127,6 +129,11 @@ static struct usb_device_id snd_usb_id_table[] = { .idVendor = USB_VID_NATIVEINSTRUMENTS, .idProduct = USB_PID_AUDIO2DJ }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_TRAKTORKONTROLX1 + }, { /* terminator */ } }; diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index 44e3edf88bef..f1117ecc84fd 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h @@ -5,18 +5,20 @@ #define USB_VID_NATIVEINSTRUMENTS 0x17cc -#define USB_PID_RIGKONTROL2 0x1969 -#define USB_PID_RIGKONTROL3 0x1940 -#define USB_PID_KORECONTROLLER 0x4711 -#define USB_PID_KORECONTROLLER2 0x4712 -#define USB_PID_AK1 0x0815 -#define USB_PID_AUDIO2DJ 0x041c -#define USB_PID_AUDIO4DJ 0x0839 -#define USB_PID_AUDIO8DJ 0x1978 -#define USB_PID_SESSIONIO 0x1915 -#define USB_PID_GUITARRIGMOBILE 0x0d8d +#define USB_PID_RIGKONTROL2 0x1969 +#define USB_PID_RIGKONTROL3 0x1940 +#define USB_PID_KORECONTROLLER 0x4711 +#define USB_PID_KORECONTROLLER2 0x4712 +#define USB_PID_AK1 0x0815 +#define USB_PID_AUDIO2DJ 0x041c +#define USB_PID_AUDIO4DJ 0x0839 +#define USB_PID_AUDIO8DJ 0x1978 +#define USB_PID_SESSIONIO 0x1915 +#define USB_PID_GUITARRIGMOBILE 0x0d8d +#define USB_PID_TRAKTORKONTROLX1 0x2305 #define EP1_BUFSIZE 64 +#define EP4_BUFSIZE 512 #define CAIAQ_USB_STR_LEN 0xff #define MAX_STREAMS 32 @@ -104,6 +106,8 @@ struct snd_usb_caiaqdev { struct input_dev *input_dev; char phys[64]; /* physical device path */ unsigned short keycode[64]; + struct urb *ep4_in_urb; + unsigned char ep4_in_buf[EP4_BUFSIZE]; #endif /* ALSA */ diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index a48d309bd94c..27ed0bc651ae 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c @@ -19,6 +19,7 @@ #include <linux/init.h> #include <linux/usb.h> #include <linux/usb/input.h> +#include <sound/core.h> #include <sound/pcm.h> #include "device.h" @@ -65,6 +66,8 @@ static unsigned short keycode_kore[] = { KEY_BRL_DOT5 }; +#define KONTROLX1_INPUTS 40 + #define DEG90 (range / 2) #define DEG180 (range) #define DEG270 (DEG90 + DEG180) @@ -162,6 +165,17 @@ static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, input_report_abs(input_dev, ABS_Z, (buf[4] << 8) | buf[5]); input_sync(input_dev); break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): + input_report_abs(input_dev, ABS_HAT0X, (buf[8] << 8) | buf[9]); + input_report_abs(input_dev, ABS_HAT0Y, (buf[4] << 8) | buf[5]); + input_report_abs(input_dev, ABS_HAT1X, (buf[12] << 8) | buf[13]); + input_report_abs(input_dev, ABS_HAT1Y, (buf[2] << 8) | buf[3]); + input_report_abs(input_dev, ABS_HAT2X, (buf[15] << 8) | buf[15]); + input_report_abs(input_dev, ABS_HAT2Y, (buf[0] << 8) | buf[1]); + input_report_abs(input_dev, ABS_HAT3X, (buf[10] << 8) | buf[11]); + input_report_abs(input_dev, ABS_HAT3Y, (buf[6] << 8) | buf[7]); + input_sync(input_dev); + break; } } @@ -201,7 +215,7 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, } static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, - char *buf, unsigned int len) + unsigned char *buf, unsigned int len) { struct input_dev *input_dev = dev->input_dev; unsigned short *keycode = input_dev->keycode; @@ -218,15 +232,84 @@ static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, input_report_key(input_dev, keycode[i], buf[i / 8] & (1 << (i % 8))); - if (dev->chip.usb_id == - USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER) || - dev->chip.usb_id == - USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2)) + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): input_report_abs(dev->input_dev, ABS_MISC, 255 - buf[4]); + break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): + /* rotary encoders */ + input_report_abs(dev->input_dev, ABS_X, buf[5] & 0xf); + input_report_abs(dev->input_dev, ABS_Y, buf[5] >> 4); + input_report_abs(dev->input_dev, ABS_Z, buf[6] & 0xf); + input_report_abs(dev->input_dev, ABS_MISC, buf[6] >> 4); + break; + } input_sync(input_dev); } +static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) +{ + struct snd_usb_caiaqdev *dev = urb->context; + unsigned char *buf = urb->transfer_buffer; + int ret; + + if (urb->status || !dev || urb != dev->ep4_in_urb) + return; + + if (urb->actual_length < 24) + goto requeue; + + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): + if (buf[0] & 0x3) + snd_caiaq_input_read_io(dev, buf + 1, 7); + + if (buf[0] & 0x4) + snd_caiaq_input_read_analog(dev, buf + 8, 16); + + break; + } + +requeue: + dev->ep4_in_urb->actual_length = 0; + ret = usb_submit_urb(dev->ep4_in_urb, GFP_ATOMIC); + if (ret < 0) + log("unable to submit urb. OOM!?\n"); +} + +static int snd_usb_caiaq_input_open(struct input_dev *idev) +{ + struct snd_usb_caiaqdev *dev = input_get_drvdata(idev); + + if (!dev) + return -EINVAL; + + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): + if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) + return -EIO; + break; + } + + return 0; +} + +static void snd_usb_caiaq_input_close(struct input_dev *idev) +{ + struct snd_usb_caiaqdev *dev = input_get_drvdata(idev); + + if (!dev) + return; + + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): + usb_kill_urb(dev->ep4_in_urb); + break; + } +} + void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len) @@ -251,7 +334,7 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) { struct usb_device *usb_dev = dev->chip.dev; struct input_dev *input; - int i, ret; + int i, ret = 0; input = input_allocate_device(); if (!input) @@ -265,7 +348,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) usb_to_input_id(usb_dev, &input->id); input->dev.parent = &usb_dev->dev; - switch (dev->chip.usb_id) { + input_set_drvdata(input, dev); + + switch (dev->chip.usb_id) { case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | @@ -326,25 +411,72 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1); snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): + input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) | + BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) | + BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) | + BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) | + BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | + BIT_MASK(ABS_Z); + input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); + BUILD_BUG_ON(sizeof(dev->keycode) < KONTROLX1_INPUTS); + for (i = 0; i < KONTROLX1_INPUTS; i++) + dev->keycode[i] = BTN_MISC + i; + input->keycodemax = KONTROLX1_INPUTS; + + /* analog potentiometers */ + input_set_abs_params(input, ABS_HAT0X, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_HAT0Y, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_HAT1X, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_HAT1Y, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_HAT2X, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_HAT2Y, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_HAT3X, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_HAT3Y, 0, 4096, 0, 10); + + /* rotary encoders */ + input_set_abs_params(input, ABS_X, 0, 0xf, 0, 1); + input_set_abs_params(input, ABS_Y, 0, 0xf, 0, 1); + input_set_abs_params(input, ABS_Z, 0, 0xf, 0, 1); + input_set_abs_params(input, ABS_MISC, 0, 0xf, 0, 1); + + dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->ep4_in_urb) { + ret = -ENOMEM; + goto exit_free_idev; + } + + usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev, + usb_rcvbulkpipe(usb_dev, 0x4), + dev->ep4_in_buf, EP4_BUFSIZE, + snd_usb_caiaq_ep4_reply_dispatch, dev); + + snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); + + break; default: /* no input methods supported on this device */ - input_free_device(input); - return 0; + goto exit_free_idev; } + input->open = snd_usb_caiaq_input_open; + input->close = snd_usb_caiaq_input_close; input->keycode = dev->keycode; input->keycodesize = sizeof(unsigned short); for (i = 0; i < input->keycodemax; i++) __set_bit(dev->keycode[i], input->keybit); ret = input_register_device(input); - if (ret < 0) { - input_free_device(input); - return ret; - } + if (ret < 0) + goto exit_free_idev; dev->input_dev = input; return 0; + +exit_free_idev: + input_free_device(input); + return ret; } void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) @@ -352,6 +484,10 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) if (!dev || !dev->input_dev) return; + usb_kill_urb(dev->ep4_in_urb); + usb_free_urb(dev->ep4_in_urb); + dev->ep4_in_urb = NULL; + input_unregister_device(dev->input_dev); dev->input_dev = NULL; } diff --git a/sound/usb/caiaq/midi.c b/sound/usb/caiaq/midi.c index 538e8c00d31a..2f218c77fff2 100644 --- a/sound/usb/caiaq/midi.c +++ b/sound/usb/caiaq/midi.c @@ -17,6 +17,7 @@ */ #include <linux/usb.h> +#include <linux/gfp.h> #include <sound/rawmidi.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 2c59afd99611..9e28b20cb2ce 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) DEFINE_WAIT(wait); long timeout = msecs_to_jiffies(50); + if (ep->umidi->disconnected) + return; /* * The substream buffer is empty, but some data might still be in the * currently active URBs, so we have to wait for those to complete. @@ -1123,14 +1125,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, * Frees an output endpoint. * May be called when ep hasn't been initialized completely. */ -static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) +static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep) { unsigned int i; for (i = 0; i < OUTPUT_URBS; ++i) - if (ep->urbs[i].urb) + if (ep->urbs[i].urb) { free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, ep->max_transfer); + ep->urbs[i].urb = NULL; + } +} + +static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep) +{ + snd_usbmidi_out_endpoint_clear(ep); kfree(ep); } @@ -1262,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p) usb_kill_urb(ep->out->urbs[j].urb); if (umidi->usb_protocol_ops->finish_out_endpoint) umidi->usb_protocol_ops->finish_out_endpoint(ep->out); + ep->out->active_urbs = 0; + if (ep->out->drain_urbs) { + ep->out->drain_urbs = 0; + wake_up(&ep->out->drain_wait); + } } if (ep->in) for (j = 0; j < INPUT_URBS; ++j) usb_kill_urb(ep->in->urbs[j]); /* free endpoints here; later call can result in Oops */ - if (ep->out) { - snd_usbmidi_out_endpoint_delete(ep->out); - ep->out = NULL; - } + if (ep->out) + snd_usbmidi_out_endpoint_clear(ep->out); if (ep->in) { snd_usbmidi_in_endpoint_delete(ep->in); ep->in = NULL; diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index 44deb21b1777..9ca9a13a78da 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c @@ -16,6 +16,7 @@ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <linux/slab.h> #include <linux/usb.h> #include <linux/usb/audio.h> #include <sound/core.h> diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c index 1879b72c40f8..04aafb43a13c 100644 --- a/sound/usb/usx2y/usX2Yhwdep.c +++ b/sound/usb/usx2y/usX2Yhwdep.c @@ -21,6 +21,7 @@ */ #include <linux/interrupt.h> +#include <linux/slab.h> #include <linux/usb.h> #include <sound/core.h> #include <sound/memalloc.h> diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c index 12ae0340adc0..c400ade3ff08 100644 --- a/sound/usb/usx2y/usb_stream.c +++ b/sound/usb/usx2y/usb_stream.c @@ -17,6 +17,7 @@ */ #include <linux/usb.h> +#include <linux/gfp.h> #include "usb_stream.h" diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index c42350eed2eb..cbd37f2c76d0 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c @@ -133,6 +133,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/slab.h> #include <linux/interrupt.h> #include <linux/usb.h> #include <sound/core.h> diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 74a67a85aa81..5d37d1ccf813 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -32,6 +32,7 @@ #include <linux/interrupt.h> +#include <linux/slab.h> #include <linux/usb.h> #include <sound/core.h> #include <sound/info.h> diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index 9ed6c3956ca7..2a528e56afd5 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c @@ -51,6 +51,7 @@ */ #include <linux/delay.h> +#include <linux/gfp.h> #include "usbusx2yaudio.c" #if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) && USX2Y_NRPACKS == 1) |