From c1422a6658ef6101fc5a979021487c732cb177a1 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 14 Feb 2007 13:17:49 +0100 Subject: [ALSA] ASoC Samsung S3C24xx I2S support This patch by Ben Dooks from Simtec Electronics adds ASoC I2S support for the Samsung S3C24xx CPU. Signed-off-by: Ben Dooks Signed-off-by: Graeme Gregory Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c new file mode 100644 index 0000000..df655a5 --- /dev/null +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -0,0 +1,439 @@ +/* + * s3c24xx-i2s.c -- ALSA Soc Audio Layer + * + * (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * (c) 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * + * Revision history + * 11th Dec 2006 Merged with Simtec driver + * 10th Nov 2006 Initial version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "s3c24xx-pcm.h" +#include "s3c24xx-i2s.h" + +#define S3C24XX_I2S_DEBUG 0 +#if S3C24XX_I2S_DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +static struct s3c2410_dma_client s3c24xx_dma_client_out = { + .name = "I2S PCM Stereo out" +}; + +static struct s3c2410_dma_client s3c24xx_dma_client_in = { + .name = "I2S PCM Stereo in" +}; + +static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_out = { + .client = &s3c24xx_dma_client_out, + .channel = DMACH_I2S_OUT, + .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO +}; + +static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_in = { + .client = &s3c24xx_dma_client_in, + .channel = DMACH_I2S_IN, + .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO +}; + +struct s3c24xx_i2s_info { + void __iomem *regs; + struct clk *iis_clk; +}; +static struct s3c24xx_i2s_info s3c24xx_i2s; + +static void s3c24xx_snd_txctrl(int on) +{ + u32 iisfcon; + u32 iiscon; + u32 iismod; + + DBG("Entered %s\n", __FUNCTION__); + + iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); + iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + + DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); + + if (on) { + iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE; + iiscon |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN; + iiscon &= ~S3C2410_IISCON_TXIDLE; + iismod |= S3C2410_IISMOD_TXMODE; + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + } else { + /* note, we have to disable the FIFOs otherwise bad things + * seem to happen when the DMA stops. According to the + * Samsung supplied kernel, this should allow the DMA + * engine and FIFOs to reset. If this isn't allowed, the + * DMA engine will simply freeze randomly. + */ + + iisfcon &= ~S3C2410_IISFCON_TXENABLE; + iisfcon &= ~S3C2410_IISFCON_TXDMA; + iiscon |= S3C2410_IISCON_TXIDLE; + iiscon &= ~S3C2410_IISCON_TXDMAEN; + iismod &= ~S3C2410_IISMOD_TXMODE; + + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + } + + DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); +} + +static void s3c24xx_snd_rxctrl(int on) +{ + u32 iisfcon; + u32 iiscon; + u32 iismod; + + DBG("Entered %s\n", __FUNCTION__); + + iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); + iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + + DBG("r: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); + + if (on) { + iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE; + iiscon |= S3C2410_IISCON_RXDMAEN | S3C2410_IISCON_IISEN; + iiscon &= ~S3C2410_IISCON_RXIDLE; + iismod |= S3C2410_IISMOD_RXMODE; + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + } else { + /* note, we have to disable the FIFOs otherwise bad things + * seem to happen when the DMA stops. According to the + * Samsung supplied kernel, this should allow the DMA + * engine and FIFOs to reset. If this isn't allowed, the + * DMA engine will simply freeze randomly. + */ + + iisfcon &= ~S3C2410_IISFCON_RXENABLE; + iisfcon &= ~S3C2410_IISFCON_RXDMA; + iiscon |= S3C2410_IISCON_RXIDLE; + iiscon &= ~S3C2410_IISCON_RXDMAEN; + iismod &= ~S3C2410_IISMOD_RXMODE; + + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + } + + DBG("w: IISCON: %lx IISMOD: %lx IISFCON: %lx\n", iiscon, iismod, iisfcon); +} + +/* + * Wait for the LR signal to allow synchronisation to the L/R clock + * from the codec. May only be needed for slave mode. + */ +static int s3c24xx_snd_lrsync(void) +{ + u32 iiscon; + unsigned long timeout = jiffies + msecs_to_jiffies(5); + + DBG("Entered %s\n", __FUNCTION__); + + while (1) { + iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + if (iiscon & S3C2410_IISCON_LRINDEX) + break; + + if (timeout < jiffies) + return -ETIMEDOUT; + } + + return 0; +} + +/* + * Check whether CPU is the master or slave + */ +static inline int s3c24xx_snd_is_clkmaster(void) +{ + DBG("Entered %s\n", __FUNCTION__); + + return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1; +} + +/* + * Set S3C24xx I2S DAI format + */ +static int s3c24xx_i2s_set_fmt(struct snd_soc_cpu_dai *cpu_dai, + unsigned int fmt) +{ + u32 iismod; + + DBG("Entered %s\n", __FUNCTION__); + + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + DBG("hw_params r: IISMOD: %lx \n", iismod); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + iismod |= S3C2410_IISMOD_SLAVE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_LEFT_J: + iismod |= S3C2410_IISMOD_MSB; + break; + case SND_SOC_DAIFMT_I2S: + break; + default: + return -EINVAL; + } + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + DBG("hw_params w: IISMOD: %lx \n", iismod); + return 0; +} + +static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + u32 iismod; + + DBG("Entered %s\n", __FUNCTION__); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out; + else + rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in; + + /* Working copies of register */ + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + DBG("hw_params r: IISMOD: %lx\n", iismod); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + break; + case SNDRV_PCM_FORMAT_S16_LE: + iismod |= S3C2410_IISMOD_16BIT; + break; + } + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + DBG("hw_params w: IISMOD: %lx\n", iismod); + return 0; +} + +static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) +{ + int ret = 0; + + DBG("Entered %s\n", __FUNCTION__); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (!s3c24xx_snd_is_clkmaster()) { + ret = s3c24xx_snd_lrsync(); + if (ret) + goto exit_err; + } + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c24xx_snd_rxctrl(1); + else + s3c24xx_snd_txctrl(1); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c24xx_snd_rxctrl(0); + else + s3c24xx_snd_txctrl(0); + break; + default: + ret = -EINVAL; + break; + } + +exit_err: + return ret; +} + +/* + * Set S3C24xx Clock source + */ +static int s3c24xx_i2s_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + + DBG("Entered %s\n", __FUNCTION__); + + iismod &= ~S3C2440_IISMOD_MPLL; + + switch (clk_id) { + case S3C24XX_CLKSRC_PCLK: + break; + case S3C24XX_CLKSRC_MPLL: + iismod |= S3C2440_IISMOD_MPLL; + break; + default: + return -EINVAL; + } + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + return 0; +} + +/* + * Set S3C24xx Clock dividers + */ +static int s3c24xx_i2s_set_clkdiv(struct snd_soc_cpu_dai *cpu_dai, + int div_id, int div) +{ + u32 reg; + + DBG("Entered %s\n", __FUNCTION__); + + switch (div_id) { + case S3C24XX_DIV_MCLK: + reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; + writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); + break; + case S3C24XX_DIV_BCLK: + reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); + writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); + break; + case S3C24XX_DIV_PRESCALER: + writel(div, s3c24xx_i2s.regs + S3C2410_IISPSR); + reg = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + writel(reg | S3C2410_IISCON_PSCEN, s3c24xx_i2s.regs + S3C2410_IISCON); + break; + default: + return -EINVAL; + } + + return 0; +} + +/* + * To avoid duplicating clock code, allow machine driver to + * get the clockrate from here. + */ +u32 s3c24xx_i2s_get_clockrate(void) +{ + return clk_get_rate(s3c24xx_i2s.iis_clk); +} +EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); + +static int s3c24xx_i2s_probe(struct platform_device *pdev) +{ + DBG("Entered %s\n", __FUNCTION__); + + s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); + if (s3c24xx_i2s.regs == NULL) + return -ENXIO; + + s3c24xx_i2s.iis_clk=clk_get(&pdev->dev, "iis"); + if (s3c24xx_i2s.iis_clk == NULL) { + DBG("failed to get iis_clock\n"); + return -ENODEV; + } + clk_enable(s3c24xx_i2s.iis_clk); + + /* Configure the I2S pins in correct mode */ + s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); + s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); + s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK); + s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); + s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); + + writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON); + + s3c24xx_snd_txctrl(0); + s3c24xx_snd_rxctrl(0); + + return 0; +} + +#define S3C24XX_I2S_RATES \ + (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) + +struct snd_soc_cpu_dai s3c24xx_i2s_dai = { + .name = "s3c24xx-i2s", + .id = 0, + .type = SND_SOC_DAI_I2S, + .probe = s3c24xx_i2s_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C24XX_I2S_RATES, + .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C24XX_I2S_RATES, + .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = { + .trigger = s3c24xx_i2s_trigger, + .hw_params = s3c24xx_i2s_hw_params,}, + .dai_ops = { + .set_fmt = s3c24xx_i2s_set_fmt, + .set_clkdiv = s3c24xx_i2s_set_clkdiv, + .set_sysclk = s3c24xx_i2s_set_sysclk, + }, +}; +EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); + +/* Module information */ +MODULE_AUTHOR("Ben Dooks, "); +MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/s3c24xx/s3c24xx-i2s.h new file mode 100644 index 0000000..f9ca04e --- /dev/null +++ b/sound/soc/s3c24xx/s3c24xx-i2s.h @@ -0,0 +1,35 @@ +/* + * s3c24xx-i2s.c -- ALSA Soc Audio Layer + * + * Copyright 2005 Wolfson Microelectronics PLC. + * Author: Graeme Gregory + * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Revision history + * 10th Nov 2006 Initial version. + */ + +#ifndef S3C24XXI2S_H_ +#define S3C24XXI2S_H_ + +/* clock sources */ +#define S3C24XX_CLKSRC_PCLK 0 +#define S3C24XX_CLKSRC_MPLL 1 + +/* Clock dividers */ +#define S3C24XX_DIV_MCLK 0 +#define S3C24XX_DIV_BCLK 1 +#define S3C24XX_DIV_PRESCALER 2 + +/* prescaler */ +#define S3C24XX_PRESCALE(a,b) \ + (((a - 1) << S3C2410_IISPSR_INTSHIFT) | ((b - 1) << S3C2410_IISPSR_EXTSHFIT)) + +u32 s3c24xx_i2s_get_clockrate(void); + +#endif /*S3C24XXI2S_H_*/ -- cgit v0.10.2 From c0f41bb1717ae31f806615e81b808753271dd3d9 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 14 Feb 2007 13:20:03 +0100 Subject: [ALSA] ASoC Samsung S3C24xx audio DMA This patch by Ben Dooks from Simtec Electronics adds ASoC audio DMA support for the Samsung S3C24xx CPU. Signed-off-by: Ben Dooks Signed-off-by: Graeme Gregory Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c new file mode 100644 index 0000000..f1c0b9f --- /dev/null +++ b/sound/soc/s3c24xx/s3c24xx-pcm.c @@ -0,0 +1,462 @@ +/* + * s3c24xx-pcm.c -- ALSA Soc Audio Layer + * + * (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * (c) 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Revision history + * 11th Dec 2006 Merged with Simtec driver + * 10th Nov 2006 Initial version. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "s3c24xx-pcm.h" + +#define S3C24XX_PCM_DEBUG 0 +#if S3C24XX_PCM_DEBUG +#define DBG(x...) printk(KERN_DEBUG x) +#else +#define DBG(x...) +#endif + +static const struct snd_pcm_hardware s3c24xx_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_U16_LE | + SNDRV_PCM_FMTBIT_U8 | + SNDRV_PCM_FMTBIT_S8, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 128*1024, + .period_bytes_min = PAGE_SIZE, + .period_bytes_max = PAGE_SIZE*2, + .periods_min = 2, + .periods_max = 128, + .fifo_size = 32, +}; + +struct s3c24xx_runtime_data { + spinlock_t lock; + int state; + unsigned int dma_loaded; + unsigned int dma_limit; + unsigned int dma_period; + dma_addr_t dma_start; + dma_addr_t dma_pos; + dma_addr_t dma_end; + struct s3c24xx_pcm_dma_params *params; +}; + +/* s3c24xx_pcm_enqueue + * + * place a dma buffer onto the queue for the dma system + * to handle. +*/ +static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + dma_addr_t pos = prtd->dma_pos; + int ret; + + DBG("Entered %s\n", __FUNCTION__); + + while ( prtd->dma_loaded < prtd->dma_limit) { + unsigned long len = prtd->dma_period; + + DBG("dma_loaded: %d\n",prtd->dma_loaded); + + if ((pos + len) > prtd->dma_end) { + len = prtd->dma_end - pos; + DBG(KERN_DEBUG "%s: corrected dma len %ld\n", + __FUNCTION__, len); + } + + ret = s3c2410_dma_enqueue(prtd->params->channel, substream, pos, len); + + if (ret == 0) { + prtd->dma_loaded++; + pos += prtd->dma_period; + if (pos >= prtd->dma_end) + pos = prtd->dma_start; + } else + break; + } + + prtd->dma_pos = pos; +} + +static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, + void *dev_id, int size, + enum s3c2410_dma_buffresult result) +{ + struct snd_pcm_substream *substream = dev_id; + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + + DBG("Entered %s\n", __FUNCTION__); + + if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) + return; + + if (substream) + snd_pcm_period_elapsed(substream); + + spin_lock(&prtd->lock); + if (prtd->state & ST_RUNNING) { + prtd->dma_loaded--; + s3c24xx_pcm_enqueue(substream); + } + + spin_unlock(&prtd->lock); +} + +static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + 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 s3c24xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; + unsigned long totbytes = params_buffer_bytes(params); + int ret=0; + + DBG("Entered %s\n", __FUNCTION__); + + /* return if this is a bufferless transfer e.g. + * codec <--> BT codec or GSM modem -- lg FIXME */ + if (!dma) + return 0; + + /* prepare DMA */ + prtd->params = dma; + + DBG("params %p, client %p, channel %d\n", prtd->params, + prtd->params->client, prtd->params->channel); + + ret = s3c2410_dma_request(prtd->params->channel, + prtd->params->client, NULL); + + if (ret) { + DBG(KERN_ERR "failed to get dma channel\n"); + return ret; + } + + /* channel needs configuring for mem=>device, increment memory addr, + * sync to pclk, half-word transfers to the IIS-FIFO. */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + s3c2410_dma_devconfig(prtd->params->channel, + S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC | + S3C2410_DISRCC_APB, prtd->params->dma_addr); + + s3c2410_dma_config(prtd->params->channel, + 2, S3C2410_DCON_SYNC_PCLK | S3C2410_DCON_HANDSHAKE); + } else { + s3c2410_dma_config(prtd->params->channel, + 2, S3C2410_DCON_HANDSHAKE | S3C2410_DCON_SYNC_PCLK); + + s3c2410_dma_devconfig(prtd->params->channel, + S3C2410_DMASRC_HW, 0x3, + prtd->params->dma_addr); + } + + s3c2410_dma_set_buffdone_fn(prtd->params->channel, + s3c24xx_audio_buffdone); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + runtime->dma_bytes = totbytes; + + spin_lock_irq(&prtd->lock); + prtd->dma_loaded = 0; + prtd->dma_limit = runtime->hw.periods_min; + prtd->dma_period = params_period_bytes(params); + prtd->dma_start = runtime->dma_addr; + prtd->dma_pos = prtd->dma_start; + prtd->dma_end = prtd->dma_start + totbytes; + spin_unlock_irq(&prtd->lock); + + return 0; +} + +static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + + DBG("Entered %s\n", __FUNCTION__); + + /* TODO - do we need to ensure DMA flushed */ + snd_pcm_set_runtime_buffer(substream, NULL); + + if(prtd->params) { + s3c2410_dma_free(prtd->params->channel, prtd->params->client); + prtd->params = NULL; + } + + return 0; +} + +static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + int ret = 0; + + DBG("Entered %s\n", __FUNCTION__); + + /* return if this is a bufferless transfer e.g. + * codec <--> BT codec or GSM modem -- lg FIXME */ + if (!prtd->params) + return 0; + + /* flush the DMA channel */ + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); + prtd->dma_loaded = 0; + prtd->dma_pos = prtd->dma_start; + + /* enqueue dma buffers */ + s3c24xx_pcm_enqueue(substream); + + return ret; +} + +static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + int ret = 0; + + DBG("Entered %s\n", __FUNCTION__); + + spin_lock(&prtd->lock); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + prtd->state |= ST_RUNNING; + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + prtd->state &= ~ST_RUNNING; + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP); + break; + + default: + ret = -EINVAL; + break; + } + + spin_unlock(&prtd->lock); + + return ret; +} + +static snd_pcm_uframes_t s3c24xx_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd = runtime->private_data; + unsigned long res; + dma_addr_t src, dst; + + DBG("Entered %s\n", __FUNCTION__); + + spin_lock(&prtd->lock); + s3c2410_dma_getposition(prtd->params->channel, &src, &dst); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + res = dst - prtd->dma_start; + else + res = src - prtd->dma_start; + + spin_unlock(&prtd->lock); + + DBG("Pointer %x %x\n",src,dst); + + /* we seem to be getting the odd error from the pcm library due + * to out-of-bounds pointers. this is maybe due to the dma engine + * not having loaded the new values for the channel before being + * callled... (todo - fix ) + */ + + if (res >= snd_pcm_lib_buffer_bytes(substream)) { + if (res == snd_pcm_lib_buffer_bytes(substream)) + res = 0; + } + + return bytes_to_frames(substream->runtime, res); +} + +static int s3c24xx_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd; + + int ret; + + DBG("Entered %s\n", __FUNCTION__); + + snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware); + + prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); + if (prtd == NULL) + return -ENOMEM; + + runtime->private_data = prtd; + return 0; +} + +static int s3c24xx_pcm_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd = runtime->private_data; + + DBG("Entered %s\n", __FUNCTION__); + + if(prtd) + kfree(prtd); + else + DBG("s3c24xx_pcm_close called with prtd == NULL\n"); + + return 0; +} + +static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + DBG("Entered %s\n", __FUNCTION__); + + return dma_mmap_writecombine(substream->pcm->card->dev, vma, + runtime->dma_area, + runtime->dma_addr, + runtime->dma_bytes); +} + +static struct snd_pcm_ops s3c24xx_pcm_ops = { + .open = s3c24xx_pcm_open, + .close = s3c24xx_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = s3c24xx_pcm_hw_params, + .hw_free = s3c24xx_pcm_hw_free, + .prepare = s3c24xx_pcm_prepare, + .trigger = s3c24xx_pcm_trigger, + .pointer = s3c24xx_pcm_pointer, + .mmap = s3c24xx_pcm_mmap, +}; + +static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) +{ + struct snd_pcm_substream *substream = pcm->streams[stream].substream; + struct snd_dma_buffer *buf = &substream->dma_buffer; + size_t size = s3c24xx_pcm_hardware.buffer_bytes_max; + + DBG("Entered %s\n", __FUNCTION__); + + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = pcm->card->dev; + buf->private_data = NULL; + buf->area = dma_alloc_writecombine(pcm->card->dev, size, + &buf->addr, GFP_KERNEL); + if (!buf->area) + return -ENOMEM; + buf->bytes = size; + return 0; +} + +static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + int stream; + + DBG("Entered %s\n", __FUNCTION__); + + for (stream = 0; stream < 2; stream++) { + substream = pcm->streams[stream].substream; + if (!substream) + continue; + + buf = &substream->dma_buffer; + if (!buf->area) + continue; + + dma_free_writecombine(pcm->card->dev, buf->bytes, + buf->area, buf->addr); + buf->area = NULL; + } +} + +static u64 s3c24xx_pcm_dmamask = DMA_32BIT_MASK; + +static int s3c24xx_pcm_new(struct snd_card *card, struct snd_soc_codec_dai *dai, + struct snd_pcm *pcm) +{ + int ret = 0; + + DBG("Entered %s\n", __FUNCTION__); + + if (!card->dev->dma_mask) + card->dev->dma_mask = &s3c24xx_pcm_dmamask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = 0xffffffff; + + if (dai->playback.channels_min) { + ret = s3c24xx_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_PLAYBACK); + if (ret) + goto out; + } + + if (dai->capture.channels_min) { + ret = s3c24xx_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_CAPTURE); + if (ret) + goto out; + } + out: + return ret; +} + +struct snd_soc_platform s3c24xx_soc_platform = { + .name = "s3c24xx-audio", + .pcm_ops = &s3c24xx_pcm_ops, + .pcm_new = s3c24xx_pcm_new, + .pcm_free = s3c24xx_pcm_free_dma_buffers, +}; + +EXPORT_SYMBOL_GPL(s3c24xx_soc_platform); + +MODULE_AUTHOR("Ben Dooks, "); +MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.h b/sound/soc/s3c24xx/s3c24xx-pcm.h new file mode 100644 index 0000000..5dced4a --- /dev/null +++ b/sound/soc/s3c24xx/s3c24xx-pcm.h @@ -0,0 +1,32 @@ +/* + * s3c24xx-pcm.h -- + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * ALSA PCM interface for the Samsung S3C24xx CPU + */ + +#ifndef _S3C24XX_PCM_H +#define _S3C24XX_PCM_H + +#define ST_RUNNING (1<<0) +#define ST_OPENED (1<<1) + +struct s3c24xx_pcm_dma_params { + struct s3c2410_dma_client *client; /* stream identifier */ + int channel; /* Channel ID */ + dma_addr_t dma_addr; +}; + +#define S3C24XX_DAI_I2S 0 + +extern struct snd_soc_cpu_dai s3c24xx_i2s_dai; + +/* platform data */ +extern struct snd_soc_platform s3c24xx_soc_platform; +extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; + +#endif -- cgit v0.10.2 From 86e1f0df2f88fd86657ddb993bba468a75128e02 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Wed, 14 Feb 2007 13:20:46 +0100 Subject: [ALSA] ASoC Samsung S3C24xx build This patch builds the Samsung S3C24xx audio DMA and I2S drivers. Signed-off-by: Graeme Gregory Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index dccaa4b..03e04ae 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -26,6 +26,7 @@ menu "SoC Platforms" depends on SND_SOC source "sound/soc/at91/Kconfig" source "sound/soc/pxa/Kconfig" +source "sound/soc/s3c24xx/Kconfig" endmenu # Supported codecs diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 98e6f49..0ae2e49 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -1,4 +1,4 @@ snd-soc-core-objs := soc-core.o soc-dapm.o obj-$(CONFIG_SND_SOC) += snd-soc-core.o -obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ +obj-$(CONFIG_SND_SOC) += codecs/ at91/ pxa/ s3c24xx/ diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig new file mode 100644 index 0000000..433da9f --- /dev/null +++ b/sound/soc/s3c24xx/Kconfig @@ -0,0 +1,16 @@ +menu "SoC Audio for the Samsung S3C24XX" + +config SND_S3C24XX_SOC + tristate "SoC Audio for the Samsung S3C24XX chips" + depends on ARCH_S3C2410 && SND + select SND_PCM + help + Say Y or M if you want to add support for codecs attached to + the S3C24XX AC97, I2S or SSP interface. You will also need + to select the audio interfaces to support below. + +config SND_S3C24XX_SOC_I2S + tristate + +endmenu + diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile new file mode 100644 index 0000000..6f0fffc --- /dev/null +++ b/sound/soc/s3c24xx/Makefile @@ -0,0 +1,6 @@ +# S3c24XX Platform Support +snd-soc-s3c24xx-objs := s3c24xx-pcm.o +snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o + +obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o +obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o -- cgit v0.10.2 From e2759e3366eda66b3e000171961ce92b2e01f05f Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Wed, 14 Feb 2007 13:22:41 +0100 Subject: [ALSA] isa_bus: ad1848 ad1848: port to isa_bus infrastructure Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 74e501d..d09a7fa 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,8 +32,11 @@ #include #include +#define CRD_NAME "Generic AD1848/AD1847/CS4248" +#define DEV_NAME "ad1848" + +MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Tugrul Galatali , Jaroslav Kysela "); -MODULE_DESCRIPTION("AD1848/AD1847/CS4248"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848}," "{Analog Devices,AD1847}," @@ -48,95 +51,98 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ static int thinkpad[SNDRV_CARDS]; /* Thinkpad special case */ module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for AD1848 soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for AD1848 soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable AD1848 soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for AD1848 driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for AD1848 driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(dma1, int, NULL, 0444); -MODULE_PARM_DESC(dma1, "DMA1 # for AD1848 driver."); +MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver."); module_param_array(thinkpad, bool, NULL, 0444); MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series."); -static struct platform_device *devices[SNDRV_CARDS]; +static int __devinit snd_ad1848_match(struct device *dev, unsigned int n) +{ + if (!enable[n]) + return 0; + if (port[n] == SNDRV_AUTO_PORT) { + snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); + return 0; + } + if (irq[n] == SNDRV_AUTO_IRQ) { + snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id); + return 0; + } + if (dma1[n] == SNDRV_AUTO_DMA) { + snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id); + return 0; + } + return 1; +} -static int __devinit snd_ad1848_probe(struct platform_device *pdev) +static int __devinit snd_ad1848_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; struct snd_card *card; struct snd_ad1848 *chip; struct snd_pcm *pcm; - int err; + int error; - if (port[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "ad1848: specify port\n"); + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) return -EINVAL; - } - if (irq[dev] == SNDRV_AUTO_IRQ) { - snd_printk(KERN_ERR "ad1848: specify irq\n"); - return -EINVAL; - } - if (dma1[dev] == SNDRV_AUTO_DMA) { - snd_printk(KERN_ERR "ad1848: specify dma1\n"); - return -EINVAL; - } - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; + error = snd_ad1848_create(card, port[n], irq[n], dma1[n], + thinkpad[n] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, &chip); + if (error < 0) + goto out; - if ((err = snd_ad1848_create(card, port[dev], - irq[dev], - dma1[dev], - thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT, - &chip)) < 0) - goto _err; card->private_data = chip; - if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0) - goto _err; + error = snd_ad1848_pcm(chip, 0, &pcm); + if (error < 0) + goto out; - if ((err = snd_ad1848_mixer(chip)) < 0) - goto _err; + error = snd_ad1848_mixer(chip); + if (error < 0) + goto out; strcpy(card->driver, "AD1848"); strcpy(card->shortname, pcm->name); sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", - pcm->name, chip->port, irq[dev], dma1[dev]); - - if (thinkpad[dev]) + pcm->name, chip->port, irq[n], dma1[n]); + if (thinkpad[n]) strcat(card->longname, " [Thinkpad]"); - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, dev); - if ((err = snd_card_register(card)) < 0) - goto _err; + error = snd_card_register(card); + if (error < 0) + goto out; - platform_set_drvdata(pdev, card); + dev_set_drvdata(dev, card); return 0; - _err: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int __devexit snd_ad1848_remove(struct platform_device *devptr) +static int __devexit snd_ad1848_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } #ifdef CONFIG_PM -static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state) +static int snd_ad1848_suspend(struct device *dev, unsigned int n, pm_message_t state) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = dev_get_drvdata(dev); struct snd_ad1848 *chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); @@ -144,9 +150,9 @@ static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int snd_ad1848_resume(struct platform_device *pdev) +static int snd_ad1848_resume(struct device *dev, unsigned int n) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = dev_get_drvdata(dev); struct snd_ad1848 *chip = card->private_data; chip->resume(chip); @@ -155,9 +161,8 @@ static int snd_ad1848_resume(struct platform_device *pdev) } #endif -#define SND_AD1848_DRIVER "snd_ad1848" - -static struct platform_driver snd_ad1848_driver = { +static struct isa_driver snd_ad1848_driver = { + .match = snd_ad1848_match, .probe = snd_ad1848_probe, .remove = __devexit_p(snd_ad1848_remove), #ifdef CONFIG_PM @@ -165,57 +170,19 @@ static struct platform_driver snd_ad1848_driver = { .resume = snd_ad1848_resume, #endif .driver = { - .name = SND_AD1848_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_ad1848_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_ad1848_driver); -} - static int __init alsa_card_ad1848_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_ad1848_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(SND_AD1848_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "AD1848 soundcard not found or device busy\n"); -#endif - snd_ad1848_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_ad1848_driver, SNDRV_CARDS); } static void __exit alsa_card_ad1848_exit(void) { - snd_ad1848_unregister_all(); + isa_unregister_driver(&snd_ad1848_driver); } -module_init(alsa_card_ad1848_init) -module_exit(alsa_card_ad1848_exit) +module_init(alsa_card_ad1848_init); +module_exit(alsa_card_ad1848_exit); -- cgit v0.10.2 From ab7942b202874f47d38c7ff06ccacdfbced1c4f4 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Wed, 14 Feb 2007 13:23:16 +0100 Subject: [ALSA] isa_bus: adlib adlib: port to isa_bus infrastructure. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c index 1124344..d687207 100644 --- a/sound/isa/adlib.c +++ b/sound/isa/adlib.c @@ -5,13 +5,13 @@ #include #include #include -#include +#include #include #include #include #define CRD_NAME "AdLib FM" -#define DRV_NAME "snd_adlib" +#define DEV_NAME "adlib" MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Rene Herman"); @@ -31,133 +31,99 @@ MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); -static struct platform_device *devices[SNDRV_CARDS]; +static int __devinit snd_adlib_match(struct device *dev, unsigned int n) +{ + if (!enable[n]) + return 0; + + if (port[n] == SNDRV_AUTO_PORT) { + snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); + return 0; + } + return 1; +} static void snd_adlib_free(struct snd_card *card) { release_and_free_resource(card->private_data); } -static int __devinit snd_adlib_probe(struct platform_device *device) +static int __devinit snd_adlib_probe(struct device *dev, unsigned int n) { struct snd_card *card; struct snd_opl3 *opl3; + int error; - int error, i = device->id; - - if (port[i] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR DRV_NAME ": please specify port\n"); - error = -EINVAL; - goto out0; - } - - card = snd_card_new(index[i], id[i], THIS_MODULE, 0); + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); if (!card) { - snd_printk(KERN_ERR DRV_NAME ": could not create card\n"); - error = -EINVAL; - goto out0; + snd_printk(KERN_ERR "%s: could not create card\n", dev->bus_id); + return -EINVAL; } - card->private_data = request_region(port[i], 4, CRD_NAME); + card->private_data = request_region(port[n], 4, CRD_NAME); if (!card->private_data) { - snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n"); + snd_printk(KERN_ERR "%s: could not grab ports\n", dev->bus_id); error = -EBUSY; - goto out1; + goto out; } card->private_free = snd_adlib_free; - error = snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3); + strcpy(card->driver, DEV_NAME); + strcpy(card->shortname, CRD_NAME); + sprintf(card->longname, CRD_NAME " at %#lx", port[n]); + + error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3); if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n"); - goto out1; + snd_printk(KERN_ERR "%s: could not create OPL\n", dev->bus_id); + goto out; } error = snd_opl3_hwdep_new(opl3, 0, 0, NULL); if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not create FM\n"); - goto out1; + snd_printk(KERN_ERR "%s: could not create FM\n", dev->bus_id); + goto out; } - strcpy(card->driver, DRV_NAME); - strcpy(card->shortname, CRD_NAME); - sprintf(card->longname, CRD_NAME " at %#lx", port[i]); - - snd_card_set_dev(card, &device->dev); + snd_card_set_dev(card, dev); error = snd_card_register(card); if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not register card\n"); - goto out1; + snd_printk(KERN_ERR "%s: could not register card\n", dev->bus_id); + goto out; } - platform_set_drvdata(device, card); + dev_set_drvdata(dev, card); return 0; -out1: snd_card_free(card); -out0: return error; +out: snd_card_free(card); + return error; } -static int __devexit snd_adlib_remove(struct platform_device *device) +static int __devexit snd_adlib_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(device)); - platform_set_drvdata(device, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } -static struct platform_driver snd_adlib_driver = { +static struct isa_driver snd_adlib_driver = { + .match = snd_adlib_match, .probe = snd_adlib_probe, .remove = __devexit_p(snd_adlib_remove), .driver = { - .name = DRV_NAME + .name = DEV_NAME } }; static int __init alsa_card_adlib_init(void) { - int i, cards; - - if (platform_driver_register(&snd_adlib_driver) < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not register driver\n"); - return -ENODEV; - } - - for (cards = 0, i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - - if (!enable[i]) - continue; - - device = platform_device_register_simple(DRV_NAME, i, NULL, 0); - if (IS_ERR(device)) - continue; - - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - - devices[i] = device; - cards++; - } - - if (!cards) { -#ifdef MODULE - printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n"); -#endif - platform_driver_unregister(&snd_adlib_driver); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_adlib_driver, SNDRV_CARDS); } static void __exit alsa_card_adlib_exit(void) { - int i; - - for (i = 0; i < SNDRV_CARDS; i++) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_adlib_driver); + isa_unregister_driver(&snd_adlib_driver); } module_init(alsa_card_adlib_init); -- cgit v0.10.2 From d63898c9d4ac7ac98608c29a2abb3c42b2bb3646 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Wed, 14 Feb 2007 13:23:38 +0100 Subject: [ALSA] isa_bus: cs4231 cs4231: port to isa_bus infrastructure. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index 696a5c8..ac40411 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,8 +32,11 @@ #include #include +#define CRD_NAME "Generic CS4231" +#define DEV_NAME "cs4231" + +MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("Generic CS4231"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}"); @@ -48,132 +51,136 @@ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for CS4231 soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for CS4231 soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable CS4231 soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for CS4231 driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(mpu_port, long, NULL, 0444); -MODULE_PARM_DESC(mpu_port, "MPU-401 port # for CS4231 driver."); +MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for CS4231 driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(mpu_irq, int, NULL, 0444); -MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for CS4231 driver."); +MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); module_param_array(dma1, int, NULL, 0444); -MODULE_PARM_DESC(dma1, "DMA1 # for CS4231 driver."); +MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver."); module_param_array(dma2, int, NULL, 0444); -MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver."); +MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver."); -static struct platform_device *devices[SNDRV_CARDS]; +static int __devinit snd_cs4231_match(struct device *dev, unsigned int n) +{ + if (!enable[n]) + return 0; + if (port[n] == SNDRV_AUTO_PORT) { + snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); + return 0; + } + if (irq[n] == SNDRV_AUTO_IRQ) { + snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id); + return 0; + } + if (dma1[n] == SNDRV_AUTO_DMA) { + snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id); + return 0; + } + return 1; +} -static int __init snd_cs4231_probe(struct platform_device *pdev) +static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; struct snd_card *card; - struct snd_pcm *pcm; struct snd_cs4231 *chip; - int err; + struct snd_pcm *pcm; + int error; - if (port[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "specify port\n"); - return -EINVAL; - } - if (irq[dev] == SNDRV_AUTO_IRQ) { - snd_printk(KERN_ERR "specify irq\n"); - return -EINVAL; - } - if (dma1[dev] == SNDRV_AUTO_DMA) { - snd_printk(KERN_ERR "specify dma1\n"); + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) return -EINVAL; - } - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; - if ((err = snd_cs4231_create(card, port[dev], -1, - irq[dev], - dma1[dev], - dma2[dev], - CS4231_HW_DETECT, - 0, &chip)) < 0) - goto _err; + + error = snd_cs4231_create(card, port[n], -1, irq[n], dma1[n], dma2[n], + CS4231_HW_DETECT, 0, &chip); + if (error < 0) + goto out; + card->private_data = chip; - if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) - goto _err; + error = snd_cs4231_pcm(chip, 0, &pcm); + if (error < 0) + goto out; strcpy(card->driver, "CS4231"); strcpy(card->shortname, pcm->name); + sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", - pcm->name, chip->port, irq[dev], dma1[dev]); - if (dma2[dev] >= 0) - sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]); - - if ((err = snd_cs4231_mixer(chip)) < 0) - goto _err; - if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) - goto _err; - - if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { - if (mpu_irq[dev] == SNDRV_AUTO_IRQ) - mpu_irq[dev] = -1; + pcm->name, chip->port, irq[n], dma1[n]); + if (dma2[n] >= 0) + sprintf(card->longname + strlen(card->longname), "&%d", dma2[n]); + + error = snd_cs4231_mixer(chip); + if (error < 0) + goto out; + + error = snd_cs4231_timer(chip, 0, NULL); + if (error < 0) + goto out; + + if (mpu_port[n] > 0 && mpu_port[n] != SNDRV_AUTO_PORT) { + if (mpu_irq[n] == SNDRV_AUTO_IRQ) + mpu_irq[n] = -1; if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, - mpu_port[dev], 0, - mpu_irq[dev], - mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, + mpu_port[n], 0, mpu_irq[n], + mpu_irq[n] >= 0 ? IRQF_DISABLED : 0, NULL) < 0) - printk(KERN_WARNING "cs4231: MPU401 not detected\n"); + printk(KERN_WARNING "%s: MPU401 not detected\n", dev->bus_id); } - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, dev); - if ((err = snd_card_register(card)) < 0) - goto _err; + error = snd_card_register(card); + if (error < 0) + goto out; - platform_set_drvdata(pdev, card); + dev_set_drvdata(dev, card); return 0; - _err: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int __devexit snd_cs4231_remove(struct platform_device *devptr) +static int __devexit snd_cs4231_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } #ifdef CONFIG_PM -static int snd_cs4231_suspend(struct platform_device *dev, pm_message_t state) +static int snd_cs4231_suspend(struct device *dev, unsigned int n, pm_message_t state) { - struct snd_card *card; - struct snd_cs4231 *chip; - card = platform_get_drvdata(dev); + struct snd_card *card = dev_get_drvdata(dev); + struct snd_cs4231 *chip = card->private_data; + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - chip = card->private_data; chip->suspend(chip); return 0; } -static int snd_cs4231_resume(struct platform_device *dev) +static int snd_cs4231_resume(struct device *dev, unsigned int n) { - struct snd_card *card; - struct snd_cs4231 *chip; - card = platform_get_drvdata(dev); - chip = card->private_data; + struct snd_card *card = dev_get_drvdata(dev); + struct snd_cs4231 *chip = card->private_data; + chip->resume(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } #endif -#define SND_CS4231_DRIVER "snd_cs4231" - -static struct platform_driver snd_cs4231_driver = { +static struct isa_driver snd_cs4231_driver = { + .match = snd_cs4231_match, .probe = snd_cs4231_probe, .remove = __devexit_p(snd_cs4231_remove), #ifdef CONFIG_PM @@ -181,57 +188,19 @@ static struct platform_driver snd_cs4231_driver = { .resume = snd_cs4231_resume, #endif .driver = { - .name = SND_CS4231_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_cs4231_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_cs4231_driver); -} - static int __init alsa_card_cs4231_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_cs4231_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(SND_CS4231_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "CS4231 soundcard not found or device busy\n"); -#endif - snd_cs4231_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_cs4231_driver, SNDRV_CARDS); } static void __exit alsa_card_cs4231_exit(void) { - snd_cs4231_unregister_all(); + isa_unregister_driver(&snd_cs4231_driver); } -module_init(alsa_card_cs4231_init) -module_exit(alsa_card_cs4231_exit) +module_init(alsa_card_cs4231_init); +module_exit(alsa_card_cs4231_exit); -- cgit v0.10.2 From ae5961869c353001e9bf1eb5bafe068959a5417f Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Wed, 14 Feb 2007 13:26:17 +0100 Subject: [ALSA] isa_bus: es1688 es1688: port to isa_bus infrastructure. very slight reorganization of the auto-probe code to be a bit easier on the eye (if not the senses). Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 65f97ff..f7d0c5f 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -35,8 +35,11 @@ #define SNDRV_LEGACY_FIND_FREE_DMA #include +#define CRD_NAME "Generic ESS ES1688/ES688 AudioDrive" +#define DEV_NAME "es1688" + +MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("ESS ESx688 AudioDrive"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100}," "{ESS,ES1688 PnP AudioDrive,pnp:ESS0102}," @@ -53,189 +56,143 @@ static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3 */ module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for ESx688 soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for ESx688 soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable ESx688 soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for ESx688 driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(mpu_port, long, NULL, 0444); -MODULE_PARM_DESC(mpu_port, "MPU-401 port # for ESx688 driver."); +MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for ESx688 driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(mpu_irq, int, NULL, 0444); -MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for ESx688 driver."); +MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); module_param_array(dma8, int, NULL, 0444); -MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver."); - -static struct platform_device *devices[SNDRV_CARDS]; +MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); -#define PFX "es1688: " +static int __devinit snd_es1688_match(struct device *dev, unsigned int n) +{ + return enable[n]; +} -static int __devinit snd_es1688_probe(struct platform_device *pdev) +static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; + static unsigned long possible_ports[] = {0x220, 0x240, 0x260}; static int possible_irqs[] = {5, 9, 10, 7, -1}; static int possible_dmas[] = {1, 3, 0, -1}; - int xirq, xdma, xmpu_irq; + int i, xirq, xdma; + struct snd_card *card; struct snd_es1688 *chip; struct snd_opl3 *opl3; struct snd_pcm *pcm; - int err; + int error; + + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; + error = -EBUSY; - xirq = irq[dev]; + xirq = irq[n]; if (xirq == SNDRV_AUTO_IRQ) { - if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); - err = -EBUSY; - goto _err; + xirq = snd_legacy_find_free_irq(possible_irqs); + if (xirq < 0) { + snd_printk(KERN_ERR "%s: unable to find a free IRQ\n", dev->bus_id); + goto out; } } - xmpu_irq = mpu_irq[dev]; - xdma = dma8[dev]; + + xdma = dma8[n]; if (xdma == SNDRV_AUTO_DMA) { - if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA\n"); - err = -EBUSY; - goto _err; + xdma = snd_legacy_find_free_dma(possible_dmas); + if (xdma < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA\n", dev->bus_id); + goto out; } } - if (port[dev] != SNDRV_AUTO_PORT) { - if ((err = snd_es1688_create(card, port[dev], mpu_port[dev], - xirq, xmpu_irq, xdma, - ES1688_HW_AUTO, &chip)) < 0) - goto _err; - } else { - /* auto-probe legacy ports */ - static unsigned long possible_ports[] = { - 0x220, 0x240, 0x260, - }; - int i; - for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { - err = snd_es1688_create(card, possible_ports[i], - mpu_port[dev], - xirq, xmpu_irq, xdma, - ES1688_HW_AUTO, &chip); - if (err >= 0) { - port[dev] = possible_ports[i]; - break; - } - } - if (i >= ARRAY_SIZE(possible_ports)) - goto _err; - } + if (port[n] == SNDRV_AUTO_PORT) + for (i = 0; i < ARRAY_SIZE(possible_ports) && error < 0; i++) + error = snd_es1688_create(card, possible_ports[i], mpu_port[n], + xirq, mpu_irq[n], xdma, ES1688_HW_AUTO, &chip); + else + error = snd_es1688_create(card, port[n], mpu_port[n], + xirq, mpu_irq[n], xdma, ES1688_HW_AUTO, &chip); + if (error < 0) + goto out; - if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0) - goto _err; + error = snd_es1688_pcm(chip, 0, &pcm); + if (error < 0) + goto out; - if ((err = snd_es1688_mixer(chip)) < 0) - goto _err; + error = snd_es1688_mixer(chip); + if (error < 0) + goto out; strcpy(card->driver, "ES1688"); strcpy(card->shortname, pcm->name); sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma); - if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) { - printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->port); - } else { - if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) - goto _err; + if (snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) + printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n", dev->bus_id, chip->port); + else { + error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); + if (error < 0) + goto out; } - if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) { - if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, - chip->mpu_port, 0, - xmpu_irq, - IRQF_DISABLED, - NULL)) < 0) - goto _err; + if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ && chip->mpu_port > 0) { + error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, chip->mpu_port, + 0, mpu_irq[n], IRQF_DISABLED, NULL); + if (error < 0) + goto out; } - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, dev); - if ((err = snd_card_register(card)) < 0) - goto _err; + error = snd_card_register(card); + if (error < 0) + goto out; - platform_set_drvdata(pdev, card); + dev_set_drvdata(dev, card); return 0; - _err: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int __devexit snd_es1688_remove(struct platform_device *devptr) +static int __devexit snd_es1688_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } -#define ES1688_DRIVER "snd_es1688" - -static struct platform_driver snd_es1688_driver = { +static struct isa_driver snd_es1688_driver = { + .match = snd_es1688_match, .probe = snd_es1688_probe, - .remove = __devexit_p(snd_es1688_remove), - /* FIXME: suspend/resume */ + .remove = snd_es1688_remove, +#if 0 /* FIXME */ + .suspend = snd_es1688_suspend, + .resume = snd_es1688_resume, +#endif .driver = { - .name = ES1688_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_es1688_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_es1688_driver); -} - static int __init alsa_card_es1688_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_es1688_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(ES1688_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n"); -#endif - snd_es1688_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS); } static void __exit alsa_card_es1688_exit(void) { - snd_es1688_unregister_all(); + isa_unregister_driver(&snd_es1688_driver); } -module_init(alsa_card_es1688_init) -module_exit(alsa_card_es1688_exit) +module_init(alsa_card_es1688_init); +module_exit(alsa_card_es1688_exit); -- cgit v0.10.2 From 07e038b349f8fadf0b5c100dc9c3cab47327a244 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 15 Feb 2007 18:23:41 +0100 Subject: [ALSA] hda-codec - Fix models for some lpatops/mobos Added the missing models for some laptops / mobos: ASUS z35m, ASRock board Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fba3cb1..4243c6b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7823,6 +7823,7 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), + SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), {} }; @@ -8336,6 +8337,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { }; static struct snd_pci_quirk alc861vd_cfg_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), -- cgit v0.10.2 From 019608b6379fcc3ba7f4db51540e509e93f4ab3c Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Mon, 19 Feb 2007 13:01:45 +0100 Subject: [ALSA] es1688 - code clean-up Seperate out the legacy probing into its own function, improving readability. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index f7d0c5f..edc3987 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -77,13 +77,48 @@ static int __devinit snd_es1688_match(struct device *dev, unsigned int n) return enable[n]; } -static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) +static int __devinit snd_es1688_legacy_create(struct snd_card *card, + struct device *dev, unsigned int n, struct snd_es1688 **rchip) { - static unsigned long possible_ports[] = {0x220, 0x240, 0x260}; + static long possible_ports[] = {0x220, 0x240, 0x260}; static int possible_irqs[] = {5, 9, 10, 7, -1}; static int possible_dmas[] = {1, 3, 0, -1}; - int i, xirq, xdma; + int i, error; + + if (irq[n] == SNDRV_AUTO_IRQ) { + irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (irq[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free IRQ\n", + dev->bus_id); + return -EBUSY; + } + } + if (dma8[n] == SNDRV_AUTO_DMA) { + dma8[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma8[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA\n", + dev->bus_id); + return -EBUSY; + } + } + + if (port[n] != SNDRV_AUTO_PORT) + return snd_es1688_create(card, port[n], mpu_port[n], irq[n], + mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); + + i = 0; + do { + port[n] = possible_ports[i]; + error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], + mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip); + } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); + + return error; +} + +static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) +{ struct snd_card *card; struct snd_es1688 *chip; struct snd_opl3 *opl3; @@ -94,33 +129,7 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) if (!card) return -EINVAL; - error = -EBUSY; - - xirq = irq[n]; - if (xirq == SNDRV_AUTO_IRQ) { - xirq = snd_legacy_find_free_irq(possible_irqs); - if (xirq < 0) { - snd_printk(KERN_ERR "%s: unable to find a free IRQ\n", dev->bus_id); - goto out; - } - } - - xdma = dma8[n]; - if (xdma == SNDRV_AUTO_DMA) { - xdma = snd_legacy_find_free_dma(possible_dmas); - if (xdma < 0) { - snd_printk(KERN_ERR "%s: unable to find a free DMA\n", dev->bus_id); - goto out; - } - } - - if (port[n] == SNDRV_AUTO_PORT) - for (i = 0; i < ARRAY_SIZE(possible_ports) && error < 0; i++) - error = snd_es1688_create(card, possible_ports[i], mpu_port[n], - xirq, mpu_irq[n], xdma, ES1688_HW_AUTO, &chip); - else - error = snd_es1688_create(card, port[n], mpu_port[n], - xirq, mpu_irq[n], xdma, ES1688_HW_AUTO, &chip); + error = snd_es1688_legacy_create(card, dev, n, &chip); if (error < 0) goto out; @@ -134,19 +143,24 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n) strcpy(card->driver, "ES1688"); strcpy(card->shortname, pcm->name); - sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma); + sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, + chip->port, chip->irq, chip->dma8); - if (snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) - printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n", dev->bus_id, chip->port); + if (snd_opl3_create(card, chip->port, chip->port + 2, + OPL3_HW_OPL3, 0, &opl3) < 0) + printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n", + dev->bus_id, chip->port); else { error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); if (error < 0) goto out; } - if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ && chip->mpu_port > 0) { - error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, chip->mpu_port, - 0, mpu_irq[n], IRQF_DISABLED, NULL); + if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ && + chip->mpu_port > 0) { + error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, + chip->mpu_port, 0, + mpu_irq[n], IRQF_DISABLED, NULL); if (error < 0) goto out; } -- cgit v0.10.2 From 93f02c6e7e5665edfe299f4e2bac22152a90d4e2 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Mon, 19 Feb 2007 13:05:02 +0100 Subject: [ALSA] isa_bus: gusclassic gusclassic: port to isa_bus infrastructure Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index 0395e2e..8f23f43 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -33,8 +33,11 @@ #define SNDRV_LEGACY_FIND_FREE_DMA #include +#define CRD_NAME "Gravis UltraSound Classic" +#define DEV_NAME "gusclassic" + +MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("Gravis UltraSound Classic"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}"); @@ -51,32 +54,80 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24}; static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for GUS Classic soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for GUS Classic soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable GUS Classic soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for GUS Classic driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for GUS Classic driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(dma1, int, NULL, 0444); -MODULE_PARM_DESC(dma1, "DMA1 # for GUS Classic driver."); +MODULE_PARM_DESC(dma1, "DMA1 # for " CRD_NAME " driver."); module_param_array(dma2, int, NULL, 0444); -MODULE_PARM_DESC(dma2, "DMA2 # for GUS Classic driver."); +MODULE_PARM_DESC(dma2, "DMA2 # for " CRD_NAME " driver."); module_param_array(joystick_dac, int, NULL, 0444); -MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Classic driver."); +MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver."); module_param_array(channels, int, NULL, 0444); -MODULE_PARM_DESC(channels, "GF1 channels for GUS Classic driver."); +MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver."); module_param_array(pcm_channels, int, NULL, 0444); -MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver."); +MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver."); + +static int __devinit snd_gusclassic_match(struct device *dev, unsigned int n) +{ + return enable[n]; +} + +static int __devinit snd_gusclassic_create(struct snd_card *card, + struct device *dev, unsigned int n, struct snd_gus_card **rgus) +{ + static long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260}; + static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1}; + static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; + + int i, error; + + if (irq[n] == SNDRV_AUTO_IRQ) { + irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (irq[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free IRQ\n", + dev->bus_id); + return -EBUSY; + } + } + if (dma1[n] == SNDRV_AUTO_DMA) { + dma1[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma1[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA1\n", + dev->bus_id); + return -EBUSY; + } + } + if (dma2[n] == SNDRV_AUTO_DMA) { + dma2[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma2[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA2\n", + dev->bus_id); + return -EBUSY; + } + } -static struct platform_device *devices[SNDRV_CARDS]; + if (port[n] != SNDRV_AUTO_PORT) + return snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n], + 0, channels[n], pcm_channels[n], 0, rgus); + i = 0; + do { + port[n] = possible_ports[i]; + error = snd_gus_create(card, port[n], irq[n], dma1[n], dma2[n], + 0, channels[n], pcm_channels[n], 0, rgus); + } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); -#define PFX "gusclassic: " + return error; +} -static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus) +static int __devinit snd_gusclassic_detect(struct snd_gus_card *gus) { unsigned char d; @@ -95,187 +146,104 @@ static int __devinit snd_gusclassic_detect(struct snd_gus_card * gus) return 0; } -static void __devinit snd_gusclassic_init(int dev, struct snd_gus_card * gus) -{ - gus->equal_irq = 0; - gus->codec_flag = 0; - gus->max_flag = 0; - gus->joystick_dac = joystick_dac[dev]; -} - -static int __devinit snd_gusclassic_probe(struct platform_device *pdev) +static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; - static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1}; - static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; - int xirq, xdma1, xdma2; struct snd_card *card; - struct snd_gus_card *gus = NULL; - int err; - - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; - if (pcm_channels[dev] < 2) - pcm_channels[dev] = 2; - - xirq = irq[dev]; - if (xirq == SNDRV_AUTO_IRQ) { - if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ\n"); - err = -EBUSY; - goto _err; - } - } - xdma1 = dma1[dev]; - if (xdma1 == SNDRV_AUTO_DMA) { - if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA1\n"); - err = -EBUSY; - goto _err; - } - } - xdma2 = dma2[dev]; - if (xdma2 == SNDRV_AUTO_DMA) { - if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA2\n"); - err = -EBUSY; - goto _err; - } - } + struct snd_gus_card *gus; + int error; - if (port[dev] != SNDRV_AUTO_PORT) { - err = snd_gus_create(card, - port[dev], - xirq, xdma1, xdma2, - 0, channels[dev], pcm_channels[dev], - 0, &gus); - } else { - /* auto-probe legacy ports */ - static unsigned long possible_ports[] = { - 0x220, 0x230, 0x240, 0x250, 0x260, - }; - int i; - for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { - err = snd_gus_create(card, - possible_ports[i], - xirq, xdma1, xdma2, - 0, channels[dev], pcm_channels[dev], - 0, &gus); - if (err >= 0) { - port[dev] = possible_ports[i]; - break; - } - } - } - if (err < 0) - goto _err; + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; - if ((err = snd_gusclassic_detect(gus)) < 0) - goto _err; + if (pcm_channels[n] < 2) + pcm_channels[n] = 2; - snd_gusclassic_init(dev, gus); - if ((err = snd_gus_initialize(gus)) < 0) - goto _err; + error = snd_gusclassic_create(card, dev, n, &gus); + if (error < 0) + goto out; + error = snd_gusclassic_detect(gus); + if (error < 0) + goto out; + + gus->joystick_dac = joystick_dac[n]; + + error = snd_gus_initialize(gus); + if (error < 0) + goto out; + + error = -ENODEV; if (gus->max_flag || gus->ess_flag) { - snd_printk(KERN_ERR PFX "GUS Classic or ACE soundcard was not detected at 0x%lx\n", gus->gf1.port); - err = -ENODEV; - goto _err; + snd_printk(KERN_ERR "%s: GUS Classic or ACE soundcard was " + "not detected at 0x%lx\n", dev->bus_id, gus->gf1.port); + goto out; } - if ((err = snd_gf1_new_mixer(gus)) < 0) - goto _err; + error = snd_gf1_new_mixer(gus); + if (error < 0) + goto out; - if ((err = snd_gf1_pcm_new(gus, 0, 0, NULL)) < 0) - goto _err; + error = snd_gf1_pcm_new(gus, 0, 0, NULL); + if (error < 0) + goto out; if (!gus->ace_flag) { - if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0) - goto _err; + error = snd_gf1_rawmidi_new(gus, 0, NULL); + if (error < 0) + goto out; } - sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %d, dma %d", gus->gf1.port, xirq, xdma1); - if (xdma2 >= 0) - sprintf(card->longname + strlen(card->longname), "&%d", xdma2); - snd_card_set_dev(card, &pdev->dev); + sprintf(card->longname + strlen(card->longname), + " at 0x%lx, irq %d, dma %d", + gus->gf1.port, gus->gf1.irq, gus->gf1.dma1); - if ((err = snd_card_register(card)) < 0) - goto _err; + if (gus->gf1.dma2 >= 0) + sprintf(card->longname + strlen(card->longname), + "&%d", gus->gf1.dma2); - platform_set_drvdata(pdev, card); + snd_card_set_dev(card, dev); + + error = snd_card_register(card); + if (error < 0) + goto out; + + dev_set_drvdata(dev, card); return 0; - _err: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int __devexit snd_gusclassic_remove(struct platform_device *devptr) +static int __devexit snd_gusclassic_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } -#define GUSCLASSIC_DRIVER "snd_gusclassic" - -static struct platform_driver snd_gusclassic_driver = { +static struct isa_driver snd_gusclassic_driver = { + .match = snd_gusclassic_match, .probe = snd_gusclassic_probe, .remove = __devexit_p(snd_gusclassic_remove), - /* FIXME: suspend/resume */ +#if 0 /* FIXME */ + .suspend = snd_gusclassic_suspend, + .remove = snd_gusclassic_remove, +#endif .driver = { - .name = GUSCLASSIC_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_gusclassic_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_gusclassic_driver); -} - static int __init alsa_card_gusclassic_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_gusclassic_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(GUSCLASSIC_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "GUS Classic soundcard not found or device busy\n"); -#endif - snd_gusclassic_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_gusclassic_driver, SNDRV_CARDS); } static void __exit alsa_card_gusclassic_exit(void) { - snd_gusclassic_unregister_all(); + isa_unregister_driver(&snd_gusclassic_driver); } -module_init(alsa_card_gusclassic_init) -module_exit(alsa_card_gusclassic_exit) +module_init(alsa_card_gusclassic_init); +module_exit(alsa_card_gusclassic_exit); -- cgit v0.10.2 From b44dfe1a4a39dbf55d204486a45aa3263eb12df0 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Mon, 19 Feb 2007 13:07:17 +0100 Subject: [ALSA] isa_bus: gusextreeme gusextreme: port to isa_bus infrastructure Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 4f55fc3..74e34e6 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -37,8 +37,11 @@ #define SNDRV_LEGACY_FIND_FREE_DMA #include +#define CRD_NAME "Gravis UltraSound Extreme" +#define DEV_NAME "gusextreme" + +MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Jaroslav Kysela "); -MODULE_DESCRIPTION("Gravis UltraSound Extreme"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}"); @@ -59,43 +62,107 @@ static int channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 24}; static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for GUS Extreme soundcard."); +MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string for GUS Extreme soundcard."); +MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard."); module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable GUS Extreme soundcard."); +MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard."); module_param_array(port, long, NULL, 0444); -MODULE_PARM_DESC(port, "Port # for GUS Extreme driver."); +MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); module_param_array(gf1_port, long, NULL, 0444); -MODULE_PARM_DESC(gf1_port, "GF1 port # for GUS Extreme driver (optional)."); +MODULE_PARM_DESC(gf1_port, "GF1 port # for " CRD_NAME " driver (optional)."); module_param_array(mpu_port, long, NULL, 0444); -MODULE_PARM_DESC(mpu_port, "MPU-401 port # for GUS Extreme driver."); +MODULE_PARM_DESC(mpu_port, "MPU-401 port # for " CRD_NAME " driver."); module_param_array(irq, int, NULL, 0444); -MODULE_PARM_DESC(irq, "IRQ # for GUS Extreme driver."); +MODULE_PARM_DESC(irq, "IRQ # for " CRD_NAME " driver."); module_param_array(mpu_irq, int, NULL, 0444); -MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for GUS Extreme driver."); +MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver."); module_param_array(gf1_irq, int, NULL, 0444); -MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for GUS Extreme driver."); +MODULE_PARM_DESC(gf1_irq, "GF1 IRQ # for " CRD_NAME " driver."); module_param_array(dma8, int, NULL, 0444); -MODULE_PARM_DESC(dma8, "8-bit DMA # for GUS Extreme driver."); +MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver."); module_param_array(dma1, int, NULL, 0444); -MODULE_PARM_DESC(dma1, "GF1 DMA # for GUS Extreme driver."); +MODULE_PARM_DESC(dma1, "GF1 DMA # for " CRD_NAME " driver."); module_param_array(joystick_dac, int, NULL, 0444); -MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for GUS Extreme driver."); +MODULE_PARM_DESC(joystick_dac, "Joystick DAC level 0.59V-4.52V or 0.389V-2.98V for " CRD_NAME " driver."); module_param_array(channels, int, NULL, 0444); -MODULE_PARM_DESC(channels, "GF1 channels for GUS Extreme driver."); +MODULE_PARM_DESC(channels, "GF1 channels for " CRD_NAME " driver."); module_param_array(pcm_channels, int, NULL, 0444); -MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver."); +MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for " CRD_NAME " driver."); + +static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n) +{ + return enable[n]; +} + +static int __devinit snd_gusextreme_es1688_create(struct snd_card *card, + struct device *dev, unsigned int n, struct snd_es1688 **rchip) +{ + static long possible_ports[] = {0x220, 0x240, 0x260}; + static int possible_irqs[] = {5, 9, 10, 7, -1}; + static int possible_dmas[] = {1, 3, 0, -1}; + + int i, error; + + if (irq[n] == SNDRV_AUTO_IRQ) { + irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (irq[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free IRQ " + "for ES1688\n", dev->bus_id); + return -EBUSY; + } + } + if (dma8[n] == SNDRV_AUTO_DMA) { + dma8[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma8[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA " + "for ES1688\n", dev->bus_id); + return -EBUSY; + } + } -static struct platform_device *devices[SNDRV_CARDS]; + if (port[n] != SNDRV_AUTO_PORT) + return snd_es1688_create(card, port[n], mpu_port[n], irq[n], + mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); + i = 0; + do { + port[n] = possible_ports[i]; + error = snd_es1688_create(card, port[n], mpu_port[n], irq[n], + mpu_irq[n], dma8[n], ES1688_HW_1688, rchip); + } while (error < 0 && ++i < ARRAY_SIZE(possible_ports)); -#define PFX "gusextreme: " + return error; +} -static int __devinit snd_gusextreme_detect(int dev, - struct snd_card *card, - struct snd_gus_card * gus, - struct snd_es1688 *es1688) +static int __devinit snd_gusextreme_gus_card_create(struct snd_card *card, + struct device *dev, unsigned int n, struct snd_gus_card **rgus) +{ + static int possible_irqs[] = {11, 12, 15, 9, 5, 7, 3, -1}; + static int possible_dmas[] = {5, 6, 7, 3, 1, -1}; + + if (gf1_irq[n] == SNDRV_AUTO_IRQ) { + gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs); + if (gf1_irq[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free IRQ " + "for GF1\n", dev->bus_id); + return -EBUSY; + } + } + if (dma1[n] == SNDRV_AUTO_DMA) { + dma1[n] = snd_legacy_find_free_dma(possible_dmas); + if (dma1[n] < 0) { + snd_printk(KERN_ERR "%s: unable to find a free DMA " + "for GF1\n", dev->bus_id); + return -EBUSY; + } + } + return snd_gus_create(card, gf1_port[n], gf1_irq[n], dma1[n], -1, + 0, channels[n], pcm_channels[n], 0, rgus); +} + +static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus, + struct snd_es1688 *es1688) { unsigned long flags; unsigned char d; @@ -117,12 +184,13 @@ static int __devinit snd_gusextreme_detect(int dev, spin_lock_irqsave(&es1688->mixer_lock, flags); snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */ spin_unlock_irqrestore(&es1688->mixer_lock, flags); + spin_lock_irqsave(&es1688->reg_lock, flags); - outb(gf1_port[dev] & 0x040 ? 2 : 0, ES1688P(es1688, INIT1)); + outb(gus->gf1.port & 0x040 ? 2 : 0, ES1688P(es1688, INIT1)); outb(0, 0x201); - outb(gf1_port[dev] & 0x020 ? 2 : 0, ES1688P(es1688, INIT1)); + outb(gus->gf1.port & 0x020 ? 2 : 0, ES1688P(es1688, INIT1)); outb(0, 0x201); - outb(gf1_port[dev] & 0x010 ? 3 : 1, ES1688P(es1688, INIT1)); + outb(gus->gf1.port & 0x010 ? 3 : 1, ES1688P(es1688, INIT1)); spin_unlock_irqrestore(&es1688->reg_lock, flags); udelay(100); @@ -139,253 +207,171 @@ static int __devinit snd_gusextreme_detect(int dev, snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d); return -EIO; } - return 0; -} -static void __devinit snd_gusextreme_init(int dev, struct snd_gus_card * gus) -{ - gus->joystick_dac = joystick_dac[dev]; + return 0; } static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip) { struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; - int err; + int error; memset(&id1, 0, sizeof(id1)); memset(&id2, 0, sizeof(id2)); id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER; + /* reassign AUX to SYNTHESIZER */ strcpy(id1.name, "Aux Playback Volume"); strcpy(id2.name, "Synth Playback Volume"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) - return err; + error = snd_ctl_rename_id(card, &id1, &id2); + if (error < 0) + return error; + /* reassign Master Playback Switch to Synth Playback Switch */ strcpy(id1.name, "Master Playback Switch"); strcpy(id2.name, "Synth Playback Switch"); - if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) - return err; + error = snd_ctl_rename_id(card, &id1, &id2); + if (error < 0) + return error; + return 0; } -static int __devinit snd_gusextreme_probe(struct platform_device *pdev) +static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) { - int dev = pdev->id; - static int possible_ess_irqs[] = {5, 9, 10, 7, -1}; - static int possible_ess_dmas[] = {1, 3, 0, -1}; - static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; - static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1}; - int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma; struct snd_card *card; struct snd_gus_card *gus; struct snd_es1688 *es1688; struct snd_opl3 *opl3; - int err; + int error; - card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); - if (card == NULL) - return -ENOMEM; + card = snd_card_new(index[n], id[n], THIS_MODULE, 0); + if (!card) + return -EINVAL; - xgf1_irq = gf1_irq[dev]; - if (xgf1_irq == SNDRV_AUTO_IRQ) { - if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n"); - err = -EBUSY; - goto out; - } - } - xess_irq = irq[dev]; - if (xess_irq == SNDRV_AUTO_IRQ) { - if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n"); - err = -EBUSY; - goto out; - } - } - if (mpu_port[dev] == SNDRV_AUTO_PORT) - mpu_port[dev] = 0; - xmpu_irq = mpu_irq[dev]; - if (xmpu_irq > 15) - xmpu_irq = -1; - xgf1_dma = dma1[dev]; - if (xgf1_dma == SNDRV_AUTO_DMA) { - if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n"); - err = -EBUSY; - goto out; - } - } - xess_dma = dma8[dev]; - if (xess_dma == SNDRV_AUTO_DMA) { - if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) { - snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n"); - err = -EBUSY; - goto out; - } - } + if (mpu_port[n] == SNDRV_AUTO_PORT) + mpu_port[n] = 0; - if (port[dev] != SNDRV_AUTO_PORT) { - err = snd_es1688_create(card, port[dev], mpu_port[dev], - xess_irq, xmpu_irq, xess_dma, - ES1688_HW_1688, &es1688); - } else { - /* auto-probe legacy ports */ - static unsigned long possible_ports[] = {0x220, 0x240, 0x260}; - int i; - for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { - err = snd_es1688_create(card, - possible_ports[i], - mpu_port[dev], - xess_irq, xmpu_irq, xess_dma, - ES1688_HW_1688, &es1688); - if (err >= 0) { - port[dev] = possible_ports[i]; - break; - } - } - } - if (err < 0) + if (mpu_irq[n] > 15) + mpu_irq[n] = -1; + + error = snd_gusextreme_es1688_create(card, dev, n, &es1688); + if (error < 0) goto out; - if (gf1_port[dev] < 0) - gf1_port[dev] = port[dev] + 0x20; - if ((err = snd_gus_create(card, - gf1_port[dev], - xgf1_irq, - xgf1_dma, - -1, - 0, channels[dev], - pcm_channels[dev], 0, - &gus)) < 0) + if (gf1_port[n] < 0) + gf1_port[n] = es1688->port + 0x20; + + error = snd_gusextreme_gus_card_create(card, dev, n, &gus); + if (error < 0) goto out; - if ((err = snd_gusextreme_detect(dev, card, gus, es1688)) < 0) + error = snd_gusextreme_detect(gus, es1688); + if (error < 0) goto out; - snd_gusextreme_init(dev, gus); - if ((err = snd_gus_initialize(gus)) < 0) + gus->joystick_dac = joystick_dac[n]; + + error = snd_gus_initialize(gus); + if (error < 0) goto out; + error = -ENODEV; if (!gus->ess_flag) { - snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port); - err = -ENODEV; + snd_printk(KERN_ERR "%s: GUS Extreme soundcard was not " + "detected at 0x%lx\n", dev->bus_id, gus->gf1.port); goto out; } - if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0) + + error = snd_es1688_pcm(es1688, 0, NULL); + if (error < 0) goto out; - if ((err = snd_es1688_mixer(es1688)) < 0) + error = snd_es1688_mixer(es1688); + if (error < 0) goto out; snd_component_add(card, "ES1688"); - if (pcm_channels[dev] > 0) { - if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0) + + if (pcm_channels[n] > 0) { + error = snd_gf1_pcm_new(gus, 1, 1, NULL); + if (error < 0) goto out; } - if ((err = snd_gf1_new_mixer(gus)) < 0) + + error = snd_gf1_new_mixer(gus); + if (error < 0) goto out; - if ((err = snd_gusextreme_mixer(es1688)) < 0) + error = snd_gusextreme_mixer(es1688); + if (error < 0) goto out; if (snd_opl3_create(card, es1688->port, es1688->port + 2, - OPL3_HW_OPL3, 0, &opl3) < 0) { - printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port); - } else { - if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0) + OPL3_HW_OPL3, 0, &opl3) < 0) + printk(KERN_ERR "%s: opl3 not detected at 0x%lx\n", + dev->bus_id, es1688->port); + else { + error = snd_opl3_hwdep_new(opl3, 0, 2, NULL); + if (error < 0) goto out; } - if (es1688->mpu_port >= 0x300 && - (err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, - es1688->mpu_port, 0, - xmpu_irq, - IRQF_DISABLED, - NULL)) < 0) - goto out; + if (es1688->mpu_port >= 0x300) { + error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, + es1688->mpu_port, 0, + mpu_irq[n], IRQF_DISABLED, NULL); + if (error < 0) + goto out; + } - sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i", - es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma); + sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, " + "irq %i&%i, dma %i&%i", es1688->port, + gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8); - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, dev); - if ((err = snd_card_register(card)) < 0) + error = snd_card_register(card); + if (error < 0) goto out; - platform_set_drvdata(pdev, card); + dev_set_drvdata(dev, card); return 0; - out: - snd_card_free(card); - return err; +out: snd_card_free(card); + return error; } -static int __devexit snd_gusextreme_remove(struct platform_device *devptr) +static int __devexit snd_gusextreme_remove(struct device *dev, unsigned int n) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(dev)); + dev_set_drvdata(dev, NULL); return 0; } -#define GUSEXTREME_DRIVER "snd_gusextreme" - -static struct platform_driver snd_gusextreme_driver = { +static struct isa_driver snd_gusextreme_driver = { + .match = snd_gusextreme_match, .probe = snd_gusextreme_probe, - .remove = __devexit_p(snd_gusextreme_remove), - /* FIXME: suspend/resume */ + .remove = snd_gusextreme_remove, +#if 0 /* FIXME */ + .suspend = snd_gusextreme_suspend, + .resume = snd_gusextreme_resume, +#endif .driver = { - .name = GUSEXTREME_DRIVER - }, + .name = DEV_NAME + } }; -static void __init_or_module snd_gusextreme_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_gusextreme_driver); -} - static int __init alsa_card_gusextreme_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_gusextreme_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(GUSEXTREME_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n"); -#endif - snd_gusextreme_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_gusextreme_driver, SNDRV_CARDS); } static void __exit alsa_card_gusextreme_exit(void) { - snd_gusextreme_unregister_all(); + isa_unregister_driver(&snd_gusextreme_driver); } -module_init(alsa_card_gusextreme_init) -module_exit(alsa_card_gusextreme_exit) +module_init(alsa_card_gusextreme_init); +module_exit(alsa_card_gusextreme_exit); -- cgit v0.10.2 From 442f4f36bed8bcadcbda299c615c12fae95eda99 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Mon, 19 Feb 2007 13:07:50 +0100 Subject: [ALSA] gusextreme: set codec_flag The gusextreme driver neglects to set the gus->codec_flag meaning snd_gf1_pcm_new() allocates a second 'PCM Playback Volume' control, which makes the driver fail to load. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 74e34e6..0aeaa6c 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c @@ -283,6 +283,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) "detected at 0x%lx\n", dev->bus_id, gus->gf1.port); goto out; } + gus->codec_flag = 1; error = snd_es1688_pcm(es1688, 0, NULL); if (error < 0) -- cgit v0.10.2 From 5e24c1c1c496c4603395d6e9cc320f85008fc891 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 22 Feb 2007 12:50:54 +0100 Subject: [ALSA] Port the rest of ALSA ISA drivers to isa_driver Port the rest of ALSA ISA drivers to use isa_driver framework instead of platform_driver. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index c09a800..456156d 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include @@ -108,7 +108,6 @@ MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver."); module_param_array(wssdma, int, NULL, 0444); MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; #ifdef CONFIG_PNP static int pnp_registered; #endif @@ -547,60 +546,70 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) return snd_card_register(card); } -static int __devinit snd_cmi8330_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_cmi8330_isa_match(struct device *pdev, + unsigned int dev) { - struct snd_card *card; - int err; - int dev = pdev->id; - + if (!enable[dev] || is_isapnp_selected(dev)) + return 0; if (wssport[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify wssport\n"); - return -EINVAL; + return 0; } if (sbport[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify sbport\n"); - return -EINVAL; + return 0; } + return 1; +} + +static int __devinit snd_cmi8330_isa_probe(struct device *pdev, + unsigned int dev) +{ + struct snd_card *card; + int err; card = snd_cmi8330_card_new(dev); if (! card) return -ENOMEM; - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_cmi8330_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devexit snd_cmi8330_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_cmi8330_isa_remove(struct device *devptr, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #ifdef CONFIG_PM -static int snd_cmi8330_nonpnp_suspend(struct platform_device *dev, pm_message_t state) +static int snd_cmi8330_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - return snd_cmi8330_suspend(platform_get_drvdata(dev)); + return snd_cmi8330_suspend(dev_get_drvdata(dev)); } -static int snd_cmi8330_nonpnp_resume(struct platform_device *dev) +static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n) { - return snd_cmi8330_resume(platform_get_drvdata(dev)); + return snd_cmi8330_resume(dev_get_drvdata(dev)); } #endif #define CMI8330_DRIVER "snd_cmi8330" -static struct platform_driver snd_cmi8330_driver = { - .probe = snd_cmi8330_nonpnp_probe, - .remove = __devexit_p(snd_cmi8330_nonpnp_remove), +static struct isa_driver snd_cmi8330_driver = { + .match = snd_cmi8330_isa_match, + .probe = snd_cmi8330_isa_probe, + .remove = __devexit_p(snd_cmi8330_isa_remove), #ifdef CONFIG_PM - .suspend = snd_cmi8330_nonpnp_suspend, - .resume = snd_cmi8330_nonpnp_resume, + .suspend = snd_cmi8330_isa_suspend, + .resume = snd_cmi8330_isa_resume, #endif .driver = { .name = CMI8330_DRIVER @@ -609,8 +618,6 @@ static struct platform_driver snd_cmi8330_driver = { #ifdef CONFIG_PNP -static unsigned int __devinitdata cmi8330_pnp_devices; - static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -640,7 +647,6 @@ static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - cmi8330_pnp_devices++; return 0; } @@ -675,63 +681,28 @@ static struct pnp_card_driver cmi8330_pnpc_driver = { }; #endif /* CONFIG_PNP */ -static void __init_or_module snd_cmi8330_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnp_registered) - pnp_unregister_card_driver(&cmi8330_pnpc_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_cmi8330_driver); -} - static int __init alsa_card_cmi8330_init(void) { - int i, err, cards = 0; + int err; - if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0) + err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) - continue; - device = platform_device_register_simple(CMI8330_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - cards++; - } - #ifdef CONFIG_PNP err = pnp_register_card_driver(&cmi8330_pnpc_driver); - if (!err) { + if (!err) pnp_registered = 1; - cards += cmi8330_pnp_devices; - } #endif - - if (!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "CMI8330 not found or device busy\n"); -#endif - snd_cmi8330_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_cmi8330_exit(void) { - snd_cmi8330_unregister_all(); +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&cmi8330_pnpc_driver); +#endif + isa_unregister_driver(&snd_cmi8330_driver); } module_init(alsa_card_cmi8330_init) diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 07ffd5c..7d9d4d5 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -126,14 +126,12 @@ MODULE_PARM_DESC(dma1, "DMA1 # for " IDENT " driver."); module_param_array(dma2, int, NULL, 0444); MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; #ifdef CONFIG_PNP static int pnpc_registered; #ifdef CS4232 static int pnp_registered; #endif #endif /* CONFIG_PNP */ -static unsigned int snd_cs423x_devices; struct snd_card_cs4236 { struct snd_cs4231 *chip; @@ -542,38 +540,55 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) return snd_card_register(card); } -static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_cs423x_isa_match(struct device *pdev, + unsigned int dev) { - int dev = pdev->id; - struct snd_card *card; - int err; + if (!enable[dev] || is_isapnp_selected(dev)) + return 0; if (port[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "specify port\n"); - return -EINVAL; + snd_printk(KERN_ERR "%s: please specify port\n", pdev->bus_id); + return 0; } if (cport[dev] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR "specify cport\n"); - return -EINVAL; + snd_printk(KERN_ERR "%s: please specify cport\n", pdev->bus_id); + return 0; + } + if (irq[dev] == SNDRV_AUTO_IRQ) { + snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id); + return 0; } + if (dma1[dev] == SNDRV_AUTO_DMA) { + snd_printk(KERN_ERR "%s: please specify dma1\n", pdev->bus_id); + return 0; + } + return 1; +} + +static int __devinit snd_cs423x_isa_probe(struct device *pdev, + unsigned int dev) +{ + struct snd_card *card; + int err; card = snd_cs423x_card_new(dev); if (! card) return -ENOMEM; - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_cs423x_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devexit snd_cs423x_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_cs423x_isa_remove(struct device *pdev, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(pdev)); + dev_set_drvdata(pdev, NULL); return 0; } @@ -594,23 +609,25 @@ static int snd_cs423x_resume(struct snd_card *card) return 0; } -static int snd_cs423x_nonpnp_suspend(struct platform_device *dev, pm_message_t state) +static int snd_cs423x_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - return snd_cs423x_suspend(platform_get_drvdata(dev)); + return snd_cs423x_suspend(dev_get_drvdata(dev)); } -static int snd_cs423x_nonpnp_resume(struct platform_device *dev) +static int snd_cs423x_isa_resume(struct device *dev, unsigned int n) { - return snd_cs423x_resume(platform_get_drvdata(dev)); + return snd_cs423x_resume(dev_get_drvdata(dev)); } #endif -static struct platform_driver cs423x_nonpnp_driver = { - .probe = snd_cs423x_nonpnp_probe, - .remove = __devexit_p(snd_cs423x_nonpnp_remove), +static struct isa_driver cs423x_isa_driver = { + .match = snd_cs423x_isa_match, + .probe = snd_cs423x_isa_probe, + .remove = __devexit_p(snd_cs423x_isa_remove), #ifdef CONFIG_PM - .suspend = snd_cs423x_nonpnp_suspend, - .resume = snd_cs423x_nonpnp_resume, + .suspend = snd_cs423x_isa_suspend, + .resume = snd_cs423x_isa_resume, #endif .driver = { .name = CS423X_DRIVER @@ -651,7 +668,6 @@ static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev, } pnp_set_drvdata(pdev, card); dev++; - snd_cs423x_devices++; return 0; } @@ -715,7 +731,6 @@ static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - snd_cs423x_devices++; return 0; } @@ -750,45 +765,13 @@ static struct pnp_card_driver cs423x_pnpc_driver = { }; #endif /* CONFIG_PNP */ -static void __init_or_module snd_cs423x_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnpc_registered) - pnp_unregister_card_driver(&cs423x_pnpc_driver); -#ifdef CS4232 - if (pnp_registered) - pnp_unregister_driver(&cs4232_pnp_driver); -#endif -#endif /* CONFIG_PNP */ - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&cs423x_nonpnp_driver); -} - static int __init alsa_card_cs423x_init(void) { - int i, err; + int err; - if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0) + err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) - continue; - device = platform_device_register_simple(CS423X_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - snd_cs423x_devices++; - } #ifdef CONFIG_PNP #ifdef CS4232 err = pnp_register_driver(&cs4232_pnp_driver); @@ -799,20 +782,20 @@ static int __init alsa_card_cs423x_init(void) if (!err) pnpc_registered = 1; #endif /* CONFIG_PNP */ - - if (!snd_cs423x_devices) { -#ifdef MODULE - printk(KERN_ERR IDENT " soundcard not found or device busy\n"); -#endif - snd_cs423x_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_cs423x_exit(void) { - snd_cs423x_unregister_all(); +#ifdef CONFIG_PNP + if (pnpc_registered) + pnp_unregister_card_driver(&cs423x_pnpc_driver); +#ifdef CS4232 + if (pnp_registered) + pnp_unregister_driver(&cs4232_pnp_driver); +#endif +#endif /* CONFIG_PNP */ + isa_unregister_driver(&cs423x_isa_driver); } module_init(alsa_card_cs423x_init) diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 725c115..12b61af 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -80,7 +80,7 @@ #include #include #include -#include +#include #include #include #include @@ -2035,8 +2035,6 @@ MODULE_PARM_DESC(dma1, "DMA 1 # for ES18xx driver."); module_param_array(dma2, int, NULL, 0444); MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; - #ifdef CONFIG_PNP static int pnp_registered, pnpc_registered; @@ -2237,7 +2235,12 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) return snd_card_register(card); } -static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr) +static int __devinit snd_es18xx_isa_match(struct device *pdev, unsigned int dev) +{ + return enable[dev] && !is_isapnp_selected(dev); +} + +static int __devinit snd_es18xx_isa_probe1(int dev, struct device *devptr) { struct snd_card *card; int err; @@ -2245,18 +2248,17 @@ static int __devinit snd_es18xx_nonpnp_probe1(int dev, struct platform_device *d card = snd_es18xx_card_new(dev); if (! card) return -ENOMEM; - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, devptr); if ((err = snd_audiodrive_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; } -static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_es18xx_isa_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; int err; static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1}; static int possible_dmas[] = {1, 0, 3, 5, -1}; @@ -2281,13 +2283,13 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev) } if (port[dev] != SNDRV_AUTO_PORT) { - return snd_es18xx_nonpnp_probe1(dev, pdev); + return snd_es18xx_isa_probe1(dev, pdev); } else { static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280}; int i; for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { port[dev] = possible_ports[i]; - err = snd_es18xx_nonpnp_probe1(dev, pdev); + err = snd_es18xx_isa_probe1(dev, pdev); if (! err) return 0; } @@ -2295,33 +2297,36 @@ static int __devinit snd_es18xx_nonpnp_probe(struct platform_device *pdev) } } -static int __devexit snd_es18xx_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_es18xx_isa_remove(struct device *devptr, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #ifdef CONFIG_PM -static int snd_es18xx_nonpnp_suspend(struct platform_device *dev, pm_message_t state) +static int snd_es18xx_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - return snd_es18xx_suspend(platform_get_drvdata(dev), state); + return snd_es18xx_suspend(dev_get_drvdata(dev), state); } -static int snd_es18xx_nonpnp_resume(struct platform_device *dev) +static int snd_es18xx_isa_resume(struct device *dev, unsigned int n) { - return snd_es18xx_resume(platform_get_drvdata(dev)); + return snd_es18xx_resume(dev_get_drvdata(dev)); } #endif #define ES18XX_DRIVER "snd_es18xx" -static struct platform_driver snd_es18xx_nonpnp_driver = { - .probe = snd_es18xx_nonpnp_probe, - .remove = __devexit_p(snd_es18xx_nonpnp_remove), +static struct isa_driver snd_es18xx_isa_driver = { + .match = snd_es18xx_isa_match, + .probe = snd_es18xx_isa_probe, + .remove = __devexit_p(snd_es18xx_isa_remove), #ifdef CONFIG_PM - .suspend = snd_es18xx_nonpnp_suspend, - .resume = snd_es18xx_nonpnp_resume, + .suspend = snd_es18xx_isa_suspend, + .resume = snd_es18xx_isa_resume, #endif .driver = { .name = ES18XX_DRIVER @@ -2330,8 +2335,6 @@ static struct platform_driver snd_es18xx_nonpnp_driver = { #ifdef CONFIG_PNP -static unsigned int __devinitdata es18xx_pnp_devices; - static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev, const struct pnp_device_id *id) { @@ -2362,7 +2365,6 @@ static int __devinit snd_audiodrive_pnp_detect(struct pnp_dev *pdev, } pnp_set_drvdata(pdev, card); dev++; - es18xx_pnp_devices++; return 0; } @@ -2424,7 +2426,6 @@ static int __devinit snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard, pnp_set_card_drvdata(pcard, card); dev++; - es18xx_pnp_devices++; return 0; } @@ -2460,44 +2461,14 @@ static struct pnp_card_driver es18xx_pnpc_driver = { }; #endif /* CONFIG_PNP */ -static void __init_or_module snd_es18xx_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnpc_registered) - pnp_unregister_card_driver(&es18xx_pnpc_driver); - if (pnp_registered) - pnp_unregister_driver(&es18xx_pnp_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_es18xx_nonpnp_driver); -} - static int __init alsa_card_es18xx_init(void) { - int i, err, cards = 0; + int err; - if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0) + err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS); + if (err < 0) return err; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) - continue; - device = platform_device_register_simple(ES18XX_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - cards++; - } - #ifdef CONFIG_PNP err = pnp_register_driver(&es18xx_pnp_driver); if (!err) @@ -2505,22 +2476,19 @@ static int __init alsa_card_es18xx_init(void) err = pnp_register_card_driver(&es18xx_pnpc_driver); if (!err) pnpc_registered = 1; - cards += es18xx_pnp_devices; -#endif - - if(!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n"); #endif - snd_es18xx_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_es18xx_exit(void) { - snd_es18xx_unregister_all(); +#ifdef CONFIG_PNP + if (pnpc_registered) + pnp_unregister_card_driver(&es18xx_pnpc_driver); + if (pnp_registered) + pnp_unregister_driver(&es18xx_pnp_driver); +#endif + isa_unregister_driver(&snd_es18xx_isa_driver); } module_init(alsa_card_es18xx_init) diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index d1ad90c..a0d2f8f 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -72,8 +72,6 @@ MODULE_PARM_DESC(channels, "Used GF1 channels for GUS MAX driver."); module_param_array(pcm_channels, int, NULL, 0444); MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver."); -static struct platform_device *devices[SNDRV_CARDS]; - struct snd_gusmax { int irq; struct snd_card *card; @@ -205,9 +203,13 @@ static void snd_gusmax_free(struct snd_card *card) free_irq(maxcard->irq, (void *)maxcard); } -static int __devinit snd_gusmax_probe(struct platform_device *pdev) +static int __devinit snd_gusmax_match(struct device *pdev, unsigned int dev) +{ + return enable[dev]; +} + +static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; static int possible_dmas[] = {5, 6, 7, 1, 3, -1}; int xirq, xdma1, xdma2, err; @@ -333,7 +335,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev) if (xdma2 >= 0) sprintf(card->longname + strlen(card->longname), "&%i", xdma2); - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_card_register(card)) < 0) goto _err; @@ -341,7 +343,7 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev) maxcard->gus = gus; maxcard->cs4231 = cs4231; - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; _err: @@ -349,16 +351,17 @@ static int __devinit snd_gusmax_probe(struct platform_device *pdev) return err; } -static int __devexit snd_gusmax_remove(struct platform_device *devptr) +static int __devexit snd_gusmax_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #define GUSMAX_DRIVER "snd_gusmax" -static struct platform_driver snd_gusmax_driver = { +static struct isa_driver snd_gusmax_driver = { + .match = snd_gusmax_match, .probe = snd_gusmax_probe, .remove = __devexit_p(snd_gusmax_remove), /* FIXME: suspend/resume */ @@ -367,52 +370,14 @@ static struct platform_driver snd_gusmax_driver = { }, }; -static void __init_or_module snd_gusmax_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_gusmax_driver); -} - static int __init alsa_card_gusmax_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_gusmax_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(GUSMAX_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "GUS MAX soundcard not found or device busy\n"); -#endif - snd_gusmax_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_gusmax_driver, SNDRV_CARDS); } static void __exit alsa_card_gusmax_exit(void) { - snd_gusmax_unregister_all(); + isa_unregister_driver(&snd_gusmax_driver); } module_init(alsa_card_gusmax_init) diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 4ec2d79..3e46572 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -115,9 +115,6 @@ MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for InterWave driver."); module_param_array(effect, int, NULL, 0444); MODULE_PARM_DESC(effect, "Effects enable for InterWave driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; -static int pnp_registered; - struct snd_interwave { int irq; struct snd_card *card; @@ -138,6 +135,7 @@ struct snd_interwave { #ifdef CONFIG_PNP +static int pnp_registered; static struct pnp_card_device_id snd_interwave_pnpids[] = { #ifndef SNDRV_STB @@ -793,7 +791,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev) return 0; } -static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr) +static int __devinit snd_interwave_isa_probe1(int dev, struct device *devptr) { struct snd_card *card; int err; @@ -802,18 +800,30 @@ static int __devinit snd_interwave_nonpnp_probe1(int dev, struct platform_device if (! card) return -ENOMEM; - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, devptr); if ((err = snd_interwave_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; } -static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_interwave_isa_match(struct device *pdev, + unsigned int dev) +{ + if (!enable[dev]) + return 0; +#ifdef CONFIG_PNP + if (isapnp[dev]) + return 0; +#endif + return 1; +} + +static int __devinit snd_interwave_isa_probe(struct device *pdev, + unsigned int dev) { - int dev = pdev->id; int err; static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1}; static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1}; @@ -838,13 +848,13 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev) } if (port[dev] != SNDRV_AUTO_PORT) - return snd_interwave_nonpnp_probe1(dev, pdev); + return snd_interwave_isa_probe1(dev, pdev); else { static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260}; int i; for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { port[dev] = possible_ports[i]; - err = snd_interwave_nonpnp_probe1(dev, pdev); + err = snd_interwave_isa_probe1(dev, pdev); if (! err) return 0; } @@ -852,16 +862,17 @@ static int __devinit snd_interwave_nonpnp_probe(struct platform_device *pdev) } } -static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_interwave_isa_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } -static struct platform_driver snd_interwave_driver = { - .probe = snd_interwave_nonpnp_probe, - .remove = __devexit_p(snd_interwave_nonpnp_remove), +static struct isa_driver snd_interwave_driver = { + .match = snd_interwave_isa_match, + .probe = snd_interwave_isa_probe, + .remove = __devexit_p(snd_interwave_isa_remove), /* FIXME: suspend,resume */ .driver = { .name = INTERWAVE_DRIVER @@ -869,8 +880,6 @@ static struct platform_driver snd_interwave_driver = { }; #ifdef CONFIG_PNP -static unsigned int __devinitdata interwave_pnp_devices; - static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -900,7 +909,6 @@ static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - interwave_pnp_devices++; return 0; } @@ -921,64 +929,29 @@ static struct pnp_card_driver interwave_pnpc_driver = { #endif /* CONFIG_PNP */ -static void __init_or_module snd_interwave_unregister_all(void) -{ - int i; - - if (pnp_registered) - pnp_unregister_card_driver(&interwave_pnpc_driver); - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_interwave_driver); -} - static int __init alsa_card_interwave_init(void) { - int i, err, cards = 0; + int err; - if ((err = platform_driver_register(&snd_interwave_driver)) < 0) + err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; #ifdef CONFIG_PNP - if (isapnp[i]) - continue; -#endif - device = platform_device_register_simple(INTERWAVE_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - cards++; - } - /* ISA PnP cards */ err = pnp_register_card_driver(&interwave_pnpc_driver); - if (!err) { + if (!err) pnp_registered = 1; - cards += interwave_pnp_devices;; - } - - if (!cards) { -#ifdef MODULE - printk(KERN_ERR "InterWave soundcard not found or device busy\n"); #endif - snd_interwave_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_interwave_exit(void) { - snd_interwave_unregister_all(); +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&interwave_pnpc_driver); +#endif + isa_unregister_driver(&snd_interwave_driver); } module_init(alsa_card_interwave_init) diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index f3db686..50a812f 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -91,12 +91,10 @@ MODULE_PARM_DESC(dma2, "DMA2 # for OPL3-SA driver."); module_param_array(opl3sa3_ymode, int, NULL, 0444); MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi."); -static struct platform_device *platform_devices[SNDRV_CARDS]; #ifdef CONFIG_PNP static int pnp_registered; static int pnpc_registered; #endif -static unsigned int snd_opl3sa2_devices; /* control ports */ #define OPL3SA2_PM_CTRL 0x01 @@ -783,7 +781,6 @@ static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev, } pnp_set_drvdata(pdev, card); dev++; - snd_opl3sa2_devices++; return 0; } @@ -850,7 +847,6 @@ static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - snd_opl3sa2_devices++; return 0; } @@ -884,116 +880,95 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = { }; #endif /* CONFIG_PNP */ -static int __devinit snd_opl3sa2_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_opl3sa2_isa_match(struct device *pdev, + unsigned int dev) { - struct snd_card *card; - int err; - int dev = pdev->id; - + if (!enable[dev]) + return 0; +#ifdef CONFIG_PNP + if (isapnp[dev]) + return 0; +#endif if (port[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify port\n"); - return -EINVAL; + return 0; } if (wss_port[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify wss_port\n"); - return -EINVAL; + return 0; } if (fm_port[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify fm_port\n"); - return -EINVAL; + return 0; } if (midi_port[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify midi_port\n"); - return -EINVAL; + return 0; } + return 1; +} + +static int __devinit snd_opl3sa2_isa_probe(struct device *pdev, + unsigned int dev) +{ + struct snd_card *card; + int err; card = snd_opl3sa2_card_new(dev); if (! card) return -ENOMEM; - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_opl3sa2_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devexit snd_opl3sa2_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_opl3sa2_isa_remove(struct device *devptr, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #ifdef CONFIG_PM -static int snd_opl3sa2_nonpnp_suspend(struct platform_device *dev, pm_message_t state) +static int snd_opl3sa2_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - return snd_opl3sa2_suspend(platform_get_drvdata(dev), state); + return snd_opl3sa2_suspend(dev_get_drvdata(dev), state); } -static int snd_opl3sa2_nonpnp_resume(struct platform_device *dev) +static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n) { - return snd_opl3sa2_resume(platform_get_drvdata(dev)); + return snd_opl3sa2_resume(dev_get_drvdata(dev)); } #endif #define OPL3SA2_DRIVER "snd_opl3sa2" -static struct platform_driver snd_opl3sa2_nonpnp_driver = { - .probe = snd_opl3sa2_nonpnp_probe, - .remove = __devexit( snd_opl3sa2_nonpnp_remove), +static struct isa_driver snd_opl3sa2_isa_driver = { + .match = snd_opl3sa2_isa_match, + .probe = snd_opl3sa2_isa_probe, + .remove = __devexit( snd_opl3sa2_isa_remove), #ifdef CONFIG_PM - .suspend = snd_opl3sa2_nonpnp_suspend, - .resume = snd_opl3sa2_nonpnp_resume, + .suspend = snd_opl3sa2_isa_suspend, + .resume = snd_opl3sa2_isa_resume, #endif .driver = { .name = OPL3SA2_DRIVER }, }; -static void __init_or_module snd_opl3sa2_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnpc_registered) - pnp_unregister_card_driver(&opl3sa2_pnpc_driver); - if (pnp_registered) - pnp_unregister_driver(&opl3sa2_pnp_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_opl3sa2_nonpnp_driver); -} - static int __init alsa_card_opl3sa2_init(void) { - int i, err; + int err; - if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0) + err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; -#ifdef CONFIG_PNP - if (isapnp[i]) - continue; -#endif - device = platform_device_register_simple(OPL3SA2_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - snd_opl3sa2_devices++; - } - #ifdef CONFIG_PNP err = pnp_register_driver(&opl3sa2_pnp_driver); if (!err) @@ -1002,20 +977,18 @@ static int __init alsa_card_opl3sa2_init(void) if (!err) pnpc_registered = 1; #endif - - if (!snd_opl3sa2_devices) { -#ifdef MODULE - snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n"); -#endif - snd_opl3sa2_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_opl3sa2_exit(void) { - snd_opl3sa2_unregister_all(); +#ifdef CONFIG_PNP + if (pnpc_registered) + pnp_unregister_card_driver(&opl3sa2_pnpc_driver); + if (pnp_registered) + pnp_unregister_driver(&opl3sa2_pnp_driver); +#endif + isa_unregister_driver(&snd_opl3sa2_isa_driver); } module_init(alsa_card_opl3sa2_init) diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 1dd9837..33471bd 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -139,8 +139,6 @@ static void snd_miro_proc_init(struct snd_miro * miro); #define DRIVER_NAME "snd-miro" -static struct platform_device *device; - static char * snd_opti9xx_names[] = { "unkown", "82C928", "82C929", @@ -558,7 +556,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new snd_miro_controls[] = { +static struct snd_kcontrol_new snd_miro_controls[] __devinitdata = { MIRO_DOUBLE("Master Playback Volume", 0, ACI_GET_MASTER, ACI_SET_MASTER), MIRO_DOUBLE("Mic Playback Volume", 1, ACI_GET_MIC, ACI_SET_MIC), MIRO_DOUBLE("Line Playback Volume", 1, ACI_GET_LINE, ACI_SET_LINE), @@ -570,7 +568,7 @@ MIRO_DOUBLE("Aux Playback Volume", 2, ACI_GET_LINE2, ACI_SET_LINE2), /* Equalizer with seven bands (only PCM20) from -12dB up to +12dB on each band */ -static struct snd_kcontrol_new snd_miro_eq_controls[] = { +static struct snd_kcontrol_new snd_miro_eq_controls[] __devinitdata = { MIRO_DOUBLE("Tone Control - 28 Hz", 0, ACI_GET_EQ1, ACI_SET_EQ1), MIRO_DOUBLE("Tone Control - 160 Hz", 0, ACI_GET_EQ2, ACI_SET_EQ2), MIRO_DOUBLE("Tone Control - 400 Hz", 0, ACI_GET_EQ3, ACI_SET_EQ3), @@ -580,15 +578,15 @@ MIRO_DOUBLE("Tone Control - 6.3 kHz", 0, ACI_GET_EQ6, ACI_SET_EQ6), MIRO_DOUBLE("Tone Control - 16 kHz", 0, ACI_GET_EQ7, ACI_SET_EQ7), }; -static struct snd_kcontrol_new snd_miro_radio_control[] = { +static struct snd_kcontrol_new snd_miro_radio_control[] __devinitdata = { MIRO_DOUBLE("Radio Playback Volume", 0, ACI_GET_LINE1, ACI_SET_LINE1), }; -static struct snd_kcontrol_new snd_miro_line_control[] = { +static struct snd_kcontrol_new snd_miro_line_control[] __devinitdata = { MIRO_DOUBLE("Line Playback Volume", 2, ACI_GET_LINE1, ACI_SET_LINE1), }; -static struct snd_kcontrol_new snd_miro_preamp_control[] = { +static struct snd_kcontrol_new snd_miro_preamp_control[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Mic Boost", @@ -598,7 +596,7 @@ static struct snd_kcontrol_new snd_miro_preamp_control[] = { .put = snd_miro_put_preamp, }}; -static struct snd_kcontrol_new snd_miro_amp_control[] = { +static struct snd_kcontrol_new snd_miro_amp_control[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Line Boost", @@ -608,7 +606,7 @@ static struct snd_kcontrol_new snd_miro_amp_control[] = { .put = snd_miro_put_amp, }}; -static struct snd_kcontrol_new snd_miro_capture_control[] = { +static struct snd_kcontrol_new snd_miro_capture_control[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "PCM Capture Switch", @@ -618,7 +616,7 @@ static struct snd_kcontrol_new snd_miro_capture_control[] = { .put = snd_miro_put_capture, }}; -static unsigned char aci_init_values[][2] __initdata = { +static unsigned char aci_init_values[][2] __devinitdata = { { ACI_SET_MUTE, 0x00 }, { ACI_SET_POWERAMP, 0x00 }, { ACI_SET_PREAMP, 0x00 }, @@ -641,7 +639,7 @@ static unsigned char aci_init_values[][2] __initdata = { { ACI_SET_MASTER + 1, 0x20 }, }; -static int __init snd_set_aci_init_values(struct snd_miro *miro) +static int __devinit snd_set_aci_init_values(struct snd_miro *miro) { int idx, error; @@ -751,7 +749,8 @@ static long snd_legacy_find_free_ioport(long *port_table, long size) return -1; } -static int __init snd_miro_init(struct snd_miro *chip, unsigned short hardware) +static int __devinit snd_miro_init(struct snd_miro *chip, + unsigned short hardware) { static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2}; @@ -962,7 +961,7 @@ static void snd_miro_proc_read(struct snd_info_entry * entry, snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp); } -static void __init snd_miro_proc_init(struct snd_miro * miro) +static void __devinit snd_miro_proc_init(struct snd_miro * miro) { struct snd_info_entry *entry; @@ -974,7 +973,7 @@ static void __init snd_miro_proc_init(struct snd_miro * miro) * Init */ -static int __init snd_miro_configure(struct snd_miro *chip) +static int __devinit snd_miro_configure(struct snd_miro *chip) { unsigned char wss_base_bits; unsigned char irq_bits; @@ -1131,7 +1130,8 @@ __skip_mpu: return 0; } -static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *chip) +static int __devinit snd_card_miro_detect(struct snd_card *card, + struct snd_miro *chip) { int i, err; unsigned char value; @@ -1157,7 +1157,8 @@ static int __init snd_card_miro_detect(struct snd_card *card, struct snd_miro *c return -ENODEV; } -static int __init snd_card_miro_aci_detect(struct snd_card *card, struct snd_miro * miro) +static int __devinit snd_card_miro_aci_detect(struct snd_card *card, + struct snd_miro * miro) { unsigned char regval; int i; @@ -1213,7 +1214,12 @@ static void snd_card_miro_free(struct snd_card *card) release_and_free_resource(miro->res_mc_base); } -static int __init snd_miro_probe(struct platform_device *devptr) +static int __devinit snd_miro_match(struct device *devptr, unsigned int n) +{ + return 1; +} + +static int __devinit snd_miro_probe(struct device *devptr, unsigned int n) { static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1}; @@ -1399,25 +1405,26 @@ static int __init snd_miro_probe(struct platform_device *devptr) return error; } - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, devptr); if ((error = snd_card_register(card))) { snd_card_free(card); return error; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; } -static int __devexit snd_miro_remove(struct platform_device *devptr) +static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } -static struct platform_driver snd_miro_driver = { +static struct isa_driver snd_miro_driver = { + .match = snd_miro_match, .probe = snd_miro_probe, .remove = __devexit_p(snd_miro_remove), /* FIXME: suspend/resume */ @@ -1428,27 +1435,12 @@ static struct platform_driver snd_miro_driver = { static int __init alsa_card_miro_init(void) { - int error; - - if ((error = platform_driver_register(&snd_miro_driver)) < 0) - return error; - device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); - if (! IS_ERR(device)) { - if (platform_get_drvdata(device)) - return 0; - platform_device_unregister(device); - } -#ifdef MODULE - printk(KERN_ERR "no miro soundcard found\n"); -#endif - platform_driver_unregister(&snd_miro_driver); - return PTR_ERR(device); + return isa_register_driver(&snd_miro_driver, 1); } static void __exit alsa_card_miro_exit(void) { - platform_device_unregister(device); - platform_driver_unregister(&snd_miro_driver); + isa_unregister_driver(&snd_miro_driver); } module_init(alsa_card_miro_init) diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index df22737..1c39058 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -259,7 +259,6 @@ struct snd_opti9xx { }; static int snd_opti9xx_pnp_is_probed; -static struct platform_device *snd_opti9xx_platform_device; #ifdef CONFIG_PNP @@ -294,7 +293,7 @@ static char * snd_opti9xx_names[] = { }; -static long __init snd_legacy_find_free_ioport(long *port_table, long size) +static long __devinit snd_legacy_find_free_ioport(long *port_table, long size) { while (*port_table != -1) { if (request_region(*port_table, size, "ALSA test")) { @@ -306,7 +305,8 @@ static long __init snd_legacy_find_free_ioport(long *port_table, long size) return -1; } -static int __init snd_opti9xx_init(struct snd_opti9xx *chip, unsigned short hardware) +static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, + unsigned short hardware) { static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2}; @@ -451,7 +451,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) -static int __init snd_opti9xx_configure(struct snd_opti9xx *chip) +static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) { unsigned char wss_base_bits; unsigned char irq_bits; @@ -1561,7 +1561,7 @@ static int snd_opti93x_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_ return change; } -static struct snd_kcontrol_new snd_opti93x_controls[] = { +static struct snd_kcontrol_new snd_opti93x_controls[] __devinitdata = { OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1), OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1), @@ -1622,7 +1622,8 @@ static int snd_opti93x_mixer(struct snd_opti93x *chip) #endif /* OPTi93X */ -static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip) +static int __devinit snd_card_opti9xx_detect(struct snd_card *card, + struct snd_opti9xx *chip) { int i, err; @@ -1676,8 +1677,9 @@ static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti } #ifdef CONFIG_PNP -static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card_link *card, - const struct pnp_card_device_id *pid) +static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, + struct pnp_card_link *card, + const struct pnp_card_device_id *pid) { struct pnp_dev *pdev; struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); @@ -1778,7 +1780,7 @@ static void snd_card_opti9xx_free(struct snd_card *card) release_and_free_resource(chip->res_mc_base); } -static int __init snd_opti9xx_probe(struct snd_card *card) +static int __devinit snd_opti9xx_probe(struct snd_card *card) { static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; int error; @@ -1924,7 +1926,18 @@ static struct snd_card *snd_opti9xx_card_new(void) return card; } -static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr) +static int __devinit snd_opti9xx_isa_match(struct device *devptr, + unsigned int dev) +{ + if (snd_opti9xx_pnp_is_probed) + return 0; + if (isapnp) + return 0; + return 1; +} + +static int __devinit snd_opti9xx_isa_probe(struct device *devptr, + unsigned int dev) { struct snd_card *card; int error; @@ -1940,9 +1953,6 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr) static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}}; #endif /* CS4231 || OPTi93X */ - if (snd_opti9xx_pnp_is_probed) - return -EBUSY; - if (mpu_port == SNDRV_AUTO_PORT) { if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) { snd_printk(KERN_ERR "unable to find a free MPU401 port\n"); @@ -1984,25 +1994,27 @@ static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr) snd_card_free(card); return error; } - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, devptr); if ((error = snd_opti9xx_probe(card)) < 0) { snd_card_free(card); return error; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; } -static int __devexit snd_opti9xx_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_opti9xx_isa_remove(struct device *devptr, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } -static struct platform_driver snd_opti9xx_driver = { - .probe = snd_opti9xx_nonpnp_probe, - .remove = __devexit_p(snd_opti9xx_nonpnp_remove), +static struct isa_driver snd_opti9xx_driver = { + .match = snd_opti9xx_isa_match, + .probe = snd_opti9xx_isa_probe, + .remove = __devexit_p(snd_opti9xx_isa_remove), /* FIXME: suspend/resume */ .driver = { .name = DRIVER_NAME @@ -2010,8 +2022,8 @@ static struct platform_driver snd_opti9xx_driver = { }; #ifdef CONFIG_PNP -static int __init snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, - const struct pnp_card_device_id *pid) +static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard, + const struct pnp_card_device_id *pid) { struct snd_card *card; int error, hw; @@ -2074,11 +2086,6 @@ static struct pnp_card_driver opti9xx_pnpc_driver = { }; #endif -#ifdef CONFIG_PNP -#define is_isapnp_selected() isapnp -#else -#define is_isapnp_selected() 0 -#endif #ifdef OPTi93X #define CHIP_NAME "82C93x" #else @@ -2087,42 +2094,19 @@ static struct pnp_card_driver opti9xx_pnpc_driver = { static int __init alsa_card_opti9xx_init(void) { - int error; - struct platform_device *device; - #ifdef CONFIG_PNP pnp_register_card_driver(&opti9xx_pnpc_driver); if (snd_opti9xx_pnp_is_probed) return 0; #endif - if (! is_isapnp_selected()) { - error = platform_driver_register(&snd_opti9xx_driver); - if (error < 0) - return error; - device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); - if (!IS_ERR(device)) { - if (platform_get_drvdata(device)) { - snd_opti9xx_platform_device = device; - return 0; - } - platform_device_unregister(device); - } - platform_driver_unregister(&snd_opti9xx_driver); - } -#ifdef CONFIG_PNP - pnp_unregister_card_driver(&opti9xx_pnpc_driver); -#endif -#ifdef MODULE - printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n"); -#endif - return -ENODEV; + return isa_register_driver(&snd_opti9xx_driver, 1); } static void __exit alsa_card_opti9xx_exit(void) { if (!snd_opti9xx_pnp_is_probed) { - platform_device_unregister(snd_opti9xx_platform_device); - platform_driver_unregister(&snd_opti9xx_driver); + isa_unregister_driver(&snd_opti9xx_driver); + return; } #ifdef CONFIG_PNP pnp_unregister_card_driver(&opti9xx_pnpc_driver); diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index d64e67f..8b734a2 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -128,7 +128,6 @@ module_param_array(seq_ports, int, NULL, 0444); MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth."); #endif -static struct platform_device *platform_devices[SNDRV_CARDS]; #ifdef CONFIG_PNP static int pnp_registered; #endif @@ -519,7 +518,7 @@ static int snd_sb16_resume(struct snd_card *card) } #endif -static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr) +static int __devinit snd_sb16_isa_probe1(int dev, struct device *pdev) { struct snd_card_sb16 *acard; struct snd_card *card; @@ -539,19 +538,23 @@ static int __devinit snd_sb16_nonpnp_probe1(int dev, struct platform_device *dev awe_port[dev] = port[dev] + 0x400; #endif - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, pdev); if ((err = snd_sb16_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(devptr, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_sb16_isa_match(struct device *pdev, unsigned int dev) +{ + return enable[dev] && !is_isapnp_selected(dev); +} + +static int __devinit snd_sb16_isa_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; int err; static int possible_irqs[] = {5, 9, 10, 7, -1}; static int possible_dmas8[] = {1, 3, 0, -1}; @@ -577,13 +580,13 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev) } if (port[dev] != SNDRV_AUTO_PORT) - return snd_sb16_nonpnp_probe1(dev, pdev); + return snd_sb16_isa_probe1(dev, pdev); else { static int possible_ports[] = {0x220, 0x240, 0x260, 0x280}; int i; for (i = 0; i < ARRAY_SIZE(possible_ports); i++) { port[dev] = possible_ports[i]; - err = snd_sb16_nonpnp_probe1(dev, pdev); + err = snd_sb16_isa_probe1(dev, pdev); if (! err) return 0; } @@ -591,22 +594,23 @@ static int __devinit snd_sb16_nonpnp_probe(struct platform_device *pdev) } } -static int __devexit snd_sb16_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_sb16_isa_remove(struct device *pdev, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(pdev)); + dev_set_drvdata(pdev, NULL); return 0; } #ifdef CONFIG_PM -static int snd_sb16_nonpnp_suspend(struct platform_device *dev, pm_message_t state) +static int snd_sb16_isa_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - return snd_sb16_suspend(platform_get_drvdata(dev), state); + return snd_sb16_suspend(dev_get_drvdata(dev), state); } -static int snd_sb16_nonpnp_resume(struct platform_device *dev) +static int snd_sb16_isa_resume(struct device *dev, unsigned int n) { - return snd_sb16_resume(platform_get_drvdata(dev)); + return snd_sb16_resume(dev_get_drvdata(dev)); } #endif @@ -616,12 +620,13 @@ static int snd_sb16_nonpnp_resume(struct platform_device *dev) #define SND_SB16_DRIVER "snd_sb16" #endif -static struct platform_driver snd_sb16_nonpnp_driver = { - .probe = snd_sb16_nonpnp_probe, - .remove = __devexit_p(snd_sb16_nonpnp_remove), +static struct isa_driver snd_sb16_isa_driver = { + .match = snd_sb16_isa_match, + .probe = snd_sb16_isa_probe, + .remove = __devexit_p(snd_sb16_isa_remove), #ifdef CONFIG_PM - .suspend = snd_sb16_nonpnp_suspend, - .resume = snd_sb16_nonpnp_resume, + .suspend = snd_sb16_isa_suspend, + .resume = snd_sb16_isa_resume, #endif .driver = { .name = SND_SB16_DRIVER @@ -630,8 +635,6 @@ static struct platform_driver snd_sb16_nonpnp_driver = { #ifdef CONFIG_PNP -static unsigned int __devinitdata sb16_pnp_devices; - static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -653,7 +656,6 @@ static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard, } pnp_set_card_drvdata(pcard, card); dev++; - sb16_pnp_devices++; return 0; } @@ -695,68 +697,29 @@ static struct pnp_card_driver sb16_pnpc_driver = { #endif /* CONFIG_PNP */ -static void __init_or_module snd_sb16_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnp_registered) - pnp_unregister_card_driver(&sb16_pnpc_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_sb16_nonpnp_driver); -} - static int __init alsa_card_sb16_init(void) { - int i, err, cards = 0; + int err; - if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0) + err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i] || is_isapnp_selected(i)) - continue; - device = platform_device_register_simple(SND_SB16_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - cards++; - } #ifdef CONFIG_PNP /* PnP cards at last */ err = pnp_register_card_driver(&sb16_pnpc_driver); - if (!err) { + if (!err) pnp_registered = 1; - cards += sb16_pnp_devices; - } -#endif - - if (!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n"); -#ifdef SNDRV_SBAWE_EMU8000 - snd_printk(KERN_ERR "In case, if you have non-AWE card, try snd-sb16 module\n"); -#else - snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n"); #endif -#endif - snd_sb16_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_sb16_exit(void) { - snd_sb16_unregister_all(); +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&sb16_pnpc_driver); +#endif + isa_unregister_driver(&snd_sb16_isa_driver); } module_init(alsa_card_sb16_init) diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index be1e83e..b7de1bc 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -56,8 +56,6 @@ MODULE_PARM_DESC(irq, "IRQ # for SB8 driver."); module_param_array(dma8, int, NULL, 0444); MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver."); -static struct platform_device *devices[SNDRV_CARDS]; - struct snd_sb8 { struct resource *fm_res; /* used to block FM i/o region for legacy cards */ struct snd_sb *chip; @@ -83,9 +81,23 @@ static void snd_sb8_free(struct snd_card *card) release_and_free_resource(acard->fm_res); } -static int __devinit snd_sb8_probe(struct platform_device *pdev) +static int __devinit snd_sb8_match(struct device *pdev, unsigned int dev) +{ + if (!enable[dev]) + return 0; + if (irq[dev] == SNDRV_AUTO_IRQ) { + snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id); + return 0; + } + if (dma8[dev] == SNDRV_AUTO_DMA) { + snd_printk(KERN_ERR "%s: please specify dma8\n", pdev->bus_id); + return 0; + } + return 1; +} + +static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; struct snd_sb *chip; struct snd_card *card; struct snd_sb8 *acard; @@ -180,12 +192,12 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev) chip->port, irq[dev], dma8[dev]); - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_card_register(card)) < 0) goto _err; - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; _err: @@ -193,17 +205,18 @@ static int __devinit snd_sb8_probe(struct platform_device *pdev) return err; } -static int __devexit snd_sb8_remove(struct platform_device *pdev) +static int __devexit snd_sb8_remove(struct device *pdev, unsigned int dev) { - snd_card_free(platform_get_drvdata(pdev)); - platform_set_drvdata(pdev, NULL); + snd_card_free(dev_get_drvdata(pdev)); + dev_set_drvdata(pdev, NULL); return 0; } #ifdef CONFIG_PM -static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state) +static int snd_sb8_suspend(struct device *dev, unsigned int n, + pm_message_t state) { - struct snd_card *card = platform_get_drvdata(dev); + struct snd_card *card = dev_get_drvdata(dev); struct snd_sb8 *acard = card->private_data; struct snd_sb *chip = acard->chip; @@ -213,9 +226,9 @@ static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state) return 0; } -static int snd_sb8_resume(struct platform_device *dev) +static int snd_sb8_resume(struct device *dev, unsigned int n) { - struct snd_card *card = platform_get_drvdata(dev); + struct snd_card *card = dev_get_drvdata(dev); struct snd_sb8 *acard = card->private_data; struct snd_sb *chip = acard->chip; @@ -228,7 +241,8 @@ static int snd_sb8_resume(struct platform_device *dev) #define SND_SB8_DRIVER "snd_sb8" -static struct platform_driver snd_sb8_driver = { +static struct isa_driver snd_sb8_driver = { + .match = snd_sb8_match, .probe = snd_sb8_probe, .remove = __devexit_p(snd_sb8_remove), #ifdef CONFIG_PM @@ -240,52 +254,14 @@ static struct platform_driver snd_sb8_driver = { }, }; -static void __init_or_module snd_sb8_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_sb8_driver); -} - static int __init alsa_card_sb8_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_sb8_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(SND_SB8_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "Sound Blaster soundcard not found or device busy\n"); -#endif - snd_sb8_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_sb8_driver, SNDRV_CARDS); } static void __exit alsa_card_sb8_exit(void) { - snd_sb8_unregister_all(); + isa_unregister_driver(&snd_sb8_driver); } module_init(alsa_card_sb8_init) diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 4fcd0f4..19e0b0e 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -64,8 +64,6 @@ MODULE_PARM_DESC(irq, "IRQ # for Sound Galaxy driver."); module_param_array(dma1, int, NULL, 0444); MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver."); -static struct platform_device *devices[SNDRV_CARDS]; - #define SGALAXY_AUXC_LEFT 18 #define SGALAXY_AUXC_RIGHT 19 @@ -96,7 +94,8 @@ static int snd_sgalaxy_sbdsp_reset(unsigned long port) return 0; } -static int __init snd_sgalaxy_sbdsp_command(unsigned long port, unsigned char val) +static int __devinit snd_sgalaxy_sbdsp_command(unsigned long port, + unsigned char val) { int i; @@ -114,7 +113,7 @@ static irqreturn_t snd_sgalaxy_dummy_interrupt(int irq, void *dev_id) return IRQ_NONE; } -static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma) +static int __devinit snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma) { static int interrupt_bits[] = {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20, -1, -1, -1, -1}; @@ -161,7 +160,7 @@ static int __init snd_sgalaxy_setup_wss(unsigned long port, int irq, int dma) return 0; } -static int __init snd_sgalaxy_detect(int dev, int irq, int dma) +static int __devinit snd_sgalaxy_detect(int dev, int irq, int dma) { #if 0 snd_printdd(PFX "switching to WSS mode\n"); @@ -182,7 +181,7 @@ AD1848_DOUBLE("Aux Playback Switch", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 7 AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0) }; -static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip) +static int __devinit snd_sgalaxy_mixer(struct snd_ad1848 *chip) { struct snd_card *card = chip->card; struct snd_ctl_elem_id id1, id2; @@ -218,23 +217,29 @@ static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip) return 0; } -static int __init snd_sgalaxy_probe(struct platform_device *devptr) +static int __devinit snd_sgalaxy_match(struct device *devptr, unsigned int dev) { - int dev = devptr->id; - static int possible_irqs[] = {7, 9, 10, 11, -1}; - static int possible_dmas[] = {1, 3, 0, -1}; - int err, xirq, xdma1; - struct snd_card *card; - struct snd_ad1848 *chip; - + if (!enable[dev]) + return 0; if (sbport[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify SB port\n"); - return -EINVAL; + return 0; } if (wssport[dev] == SNDRV_AUTO_PORT) { snd_printk(KERN_ERR PFX "specify WSS port\n"); - return -EINVAL; + return 0; } + return 1; +} + +static int __devinit snd_sgalaxy_probe(struct device *devptr, unsigned int dev) +{ + static int possible_irqs[] = {7, 9, 10, 11, -1}; + static int possible_dmas[] = {1, 3, 0, -1}; + int err, xirq, xdma1; + struct snd_card *card; + struct snd_ad1848 *chip; + card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); if (card == NULL) return -ENOMEM; @@ -283,12 +288,12 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr) sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d", wssport[dev], xirq, xdma1); - snd_card_set_dev(card, &devptr->dev); + snd_card_set_dev(card, devptr); if ((err = snd_card_register(card)) < 0) goto _err; - platform_set_drvdata(devptr, card); + dev_set_drvdata(devptr, card); return 0; _err: @@ -296,17 +301,18 @@ static int __init snd_sgalaxy_probe(struct platform_device *devptr) return err; } -static int __devexit snd_sgalaxy_remove(struct platform_device *devptr) +static int __devexit snd_sgalaxy_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #ifdef CONFIG_PM -static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state) +static int snd_sgalaxy_suspend(struct device *pdev, unsigned int n, + pm_message_t state) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = dev_get_drvdata(pdev); struct snd_ad1848 *chip = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); @@ -314,9 +320,9 @@ static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int snd_sgalaxy_resume(struct platform_device *pdev) +static int snd_sgalaxy_resume(struct device *pdev, unsigned int n) { - struct snd_card *card = platform_get_drvdata(pdev); + struct snd_card *card = dev_get_drvdata(pdev); struct snd_ad1848 *chip = card->private_data; chip->resume(chip); @@ -330,7 +336,8 @@ static int snd_sgalaxy_resume(struct platform_device *pdev) #define SND_SGALAXY_DRIVER "snd_sgalaxy" -static struct platform_driver snd_sgalaxy_driver = { +static struct isa_driver snd_sgalaxy_driver = { + .match = snd_sgalaxy_match, .probe = snd_sgalaxy_probe, .remove = __devexit_p(snd_sgalaxy_remove), #ifdef CONFIG_PM @@ -342,52 +349,14 @@ static struct platform_driver snd_sgalaxy_driver = { }, }; -static void __init_or_module snd_sgalaxy_unregister_all(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(devices); ++i) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_sgalaxy_driver); -} - static int __init alsa_card_sgalaxy_init(void) { - int i, cards, err; - - err = platform_driver_register(&snd_sgalaxy_driver); - if (err < 0) - return err; - - cards = 0; - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; - device = platform_device_register_simple(SND_SGALAXY_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - devices[i] = device; - cards++; - } - if (!cards) { -#ifdef MODULE - snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n"); -#endif - snd_sgalaxy_unregister_all(); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_sgalaxy_driver, SNDRV_CARDS); } static void __exit alsa_card_sgalaxy_exit(void) { - snd_sgalaxy_unregister_all(); + isa_unregister_driver(&snd_sgalaxy_driver); } module_init(alsa_card_sgalaxy_init) diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index b1f2582..369de44 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -68,8 +68,6 @@ MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver."); module_param_array(dma, int, NULL, 0444); MODULE_PARM_DESC(dma, "DMA # for SoundScape driver."); -static struct platform_device *platform_devices[SNDRV_CARDS]; - #ifdef CONFIG_PNP static int pnp_registered; static struct pnp_card_device_id sscape_pnpids[] = { @@ -1254,9 +1252,27 @@ static int __devinit create_sscape(int dev, struct snd_card **rcardp) } -static int __devinit snd_sscape_probe(struct platform_device *pdev) +static int __devinit snd_sscape_match(struct device *pdev, unsigned int i) +{ + /* + * Make sure we were given ALL of the other parameters. + */ + if (port[i] == SNDRV_AUTO_PORT) + return 0; + + if (irq[i] == SNDRV_AUTO_IRQ || + mpu_irq[i] == SNDRV_AUTO_IRQ || + dma[i] == SNDRV_AUTO_DMA) { + printk(KERN_INFO + "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); + return 0; + } + + return 1; +} + +static int __devinit snd_sscape_probe(struct device *pdev, unsigned int dev) { - int dev = pdev->id; struct snd_card *card; int ret; @@ -1264,25 +1280,26 @@ static int __devinit snd_sscape_probe(struct platform_device *pdev) ret = create_sscape(dev, &card); if (ret < 0) return ret; - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((ret = snd_card_register(card)) < 0) { printk(KERN_ERR "sscape: Failed to register sound card\n"); return ret; } - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devexit snd_sscape_remove(struct platform_device *devptr) +static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #define SSCAPE_DRIVER "snd_sscape" -static struct platform_driver snd_sscape_driver = { +static struct isa_driver snd_sscape_driver = { + .match = snd_sscape_match, .probe = snd_sscape_probe, .remove = __devexit_p(snd_sscape_remove), /* FIXME: suspend/resume */ @@ -1386,72 +1403,6 @@ static struct pnp_card_driver sscape_pnpc_driver = { #endif /* CONFIG_PNP */ -static void __init_or_module sscape_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnp_registered) - pnp_unregister_card_driver(&sscape_pnpc_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_sscape_driver); -} - -static int __init sscape_manual_probe(void) -{ - struct platform_device *device; - int i, ret; - - ret = platform_driver_register(&snd_sscape_driver); - if (ret < 0) - return ret; - - for (i = 0; i < SNDRV_CARDS; ++i) { - /* - * We do NOT probe for ports. - * If we're not given a port number for this - * card then we completely ignore this line - * of parameters. - */ - if (port[i] == SNDRV_AUTO_PORT) - continue; - - /* - * Make sure we were given ALL of the other parameters. - */ - if (irq[i] == SNDRV_AUTO_IRQ || - mpu_irq[i] == SNDRV_AUTO_IRQ || - dma[i] == SNDRV_AUTO_DMA) { - printk(KERN_INFO - "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n"); - sscape_unregister_all(); - return -ENXIO; - } - - /* - * This cards looks OK ... - */ - device = platform_device_register_simple(SSCAPE_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - } - return 0; -} - -static void sscape_exit(void) -{ - sscape_unregister_all(); -} - - static int __init sscape_init(void) { int ret; @@ -1462,7 +1413,7 @@ static int __init sscape_init(void) * of allocating cards, because the operator is * S-P-E-L-L-I-N-G it out for us... */ - ret = sscape_manual_probe(); + ret = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS); if (ret < 0) return ret; #ifdef CONFIG_PNP @@ -1472,5 +1423,14 @@ static int __init sscape_init(void) return 0; } +static void __exit sscape_exit(void) +{ +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&sscape_pnpc_driver); +#endif + isa_unregister_driver(&snd_sscape_driver); +} + module_init(sscape_init); module_exit(sscape_exit); diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index e2fdd5f..6f14327 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -83,8 +83,6 @@ MODULE_PARM_DESC(fm_port, "FM port #."); module_param_array(use_cs4232_midi, bool, NULL, 0444); MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)"); -static struct platform_device *platform_devices[SNDRV_CARDS]; - #ifdef CONFIG_PNP static int pnp_registered; @@ -588,46 +586,59 @@ snd_wavefront_probe (struct snd_card *card, int dev) return snd_card_register(card); } -static int __devinit snd_wavefront_nonpnp_probe(struct platform_device *pdev) +static int __devinit snd_wavefront_isa_match(struct device *pdev, + unsigned int dev) { - int dev = pdev->id; - struct snd_card *card; - int err; - + if (!enable[dev]) + return 0; +#ifdef CONFIG_PNP + if (isapnp[dev]) + return 0; +#endif if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) { snd_printk("specify CS4232 port\n"); - return -EINVAL; + return 0; } if (ics2115_port[dev] == SNDRV_AUTO_PORT) { snd_printk("specify ICS2115 port\n"); - return -ENODEV; + return 0; } + return 1; +} + +static int __devinit snd_wavefront_isa_probe(struct device *pdev, + unsigned int dev) +{ + struct snd_card *card; + int err; card = snd_wavefront_card_new(dev); if (! card) return -ENOMEM; - snd_card_set_dev(card, &pdev->dev); + snd_card_set_dev(card, pdev); if ((err = snd_wavefront_probe(card, dev)) < 0) { snd_card_free(card); return err; } - platform_set_drvdata(pdev, card); + dev_set_drvdata(pdev, card); return 0; } -static int __devexit snd_wavefront_nonpnp_remove(struct platform_device *devptr) +static int __devexit snd_wavefront_isa_remove(struct device *devptr, + unsigned int dev) { - snd_card_free(platform_get_drvdata(devptr)); - platform_set_drvdata(devptr, NULL); + snd_card_free(dev_get_drvdata(devptr)); + dev_set_drvdata(devptr, NULL); return 0; } #define WAVEFRONT_DRIVER "snd_wavefront" -static struct platform_driver snd_wavefront_driver = { - .probe = snd_wavefront_nonpnp_probe, - .remove = __devexit_p(snd_wavefront_nonpnp_remove), +static struct isa_driver snd_wavefront_driver = { + .match = snd_wavefront_isa_match, + .probe = snd_wavefront_isa_probe, + .remove = __devexit_p(snd_wavefront_isa_remove), /* FIXME: suspend, resume */ .driver = { .name = WAVEFRONT_DRIVER @@ -636,8 +647,6 @@ static struct platform_driver snd_wavefront_driver = { #ifdef CONFIG_PNP -static unsigned int __devinitdata wavefront_pnp_devices; - static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, const struct pnp_card_device_id *pid) { @@ -670,7 +679,6 @@ static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard, pnp_set_card_drvdata(pcard, card); dev++; - wavefront_pnp_devices++; return 0; } @@ -691,67 +699,28 @@ static struct pnp_card_driver wavefront_pnpc_driver = { #endif /* CONFIG_PNP */ -static void __init_or_module snd_wavefront_unregister_all(void) -{ - int i; - -#ifdef CONFIG_PNP - if (pnp_registered) - pnp_unregister_card_driver(&wavefront_pnpc_driver); -#endif - for (i = 0; i < ARRAY_SIZE(platform_devices); ++i) - platform_device_unregister(platform_devices[i]); - platform_driver_unregister(&snd_wavefront_driver); -} - static int __init alsa_card_wavefront_init(void) { - int i, err, cards = 0; + int err; - if ((err = platform_driver_register(&snd_wavefront_driver)) < 0) + err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS); + if (err < 0) return err; - - for (i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - if (! enable[i]) - continue; -#ifdef CONFIG_PNP - if (isapnp[i]) - continue; -#endif - device = platform_device_register_simple(WAVEFRONT_DRIVER, - i, NULL, 0); - if (IS_ERR(device)) - continue; - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - platform_devices[i] = device; - cards++; - } - #ifdef CONFIG_PNP err = pnp_register_card_driver(&wavefront_pnpc_driver); - if (!err) { + if (!err) pnp_registered = 1; - cards += wavefront_pnp_devices; - } -#endif - - if (!cards) { -#ifdef MODULE - printk (KERN_ERR "No WaveFront cards found or devices busy\n"); #endif - snd_wavefront_unregister_all(); - return -ENODEV; - } return 0; } static void __exit alsa_card_wavefront_exit(void) { - snd_wavefront_unregister_all(); +#ifdef CONFIG_PNP + if (pnp_registered) + pnp_unregister_card_driver(&wavefront_pnpc_driver); +#endif + isa_unregister_driver(&snd_wavefront_driver); } module_init(alsa_card_wavefront_init) -- cgit v0.10.2 From ef991b95aa1351a5782cfaccb9aefba76ca8b990 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 22 Feb 2007 12:52:53 +0100 Subject: [ALSA] Add snd_pcm_group_for_each_entry() for code cleanup Added a new macro snd_pcm_group_for_each_entry() just for code cleanup. Old macros, snd_pcm_group_for_each() and snd_pcm_group_substream_entry(), are removed. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/pcm.h b/include/sound/pcm.h index deff5a9..73334e0 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -603,11 +603,8 @@ do { \ read_unlock_irqrestore(&snd_pcm_link_rwlock, (flags)); \ } while (0) -#define snd_pcm_group_for_each(pos, substream) \ - list_for_each(pos, &substream->group->substreams) - -#define snd_pcm_group_substream_entry(pos) \ - list_entry(pos, struct snd_pcm_substream, link_list) +#define snd_pcm_group_for_each_entry(s, substream) \ + list_for_each_entry(s, &substream->group->substreams, link_list) static inline int snd_pcm_running(struct snd_pcm_substream *substream) { diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 9052348..42a039c 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -712,26 +712,22 @@ static int snd_pcm_action_group(struct action_ops *ops, struct snd_pcm_substream *substream, int state, int do_lock) { - struct list_head *pos; struct snd_pcm_substream *s = NULL; struct snd_pcm_substream *s1; int res = 0; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (do_lock && s != substream) spin_lock(&s->self_group.lock); res = ops->pre_action(s, state); if (res < 0) goto _unlock; } - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { res = ops->do_action(s, state); if (res < 0) { if (ops->undo_action) { - snd_pcm_group_for_each(pos, substream) { - s1 = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s1, substream) { if (s1 == s) /* failed stream */ break; ops->undo_action(s1, state); @@ -741,15 +737,13 @@ static int snd_pcm_action_group(struct action_ops *ops, goto _unlock; } } - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { ops->post_action(s, state); } _unlock: if (do_lock) { /* unlock streams */ - snd_pcm_group_for_each(pos, substream) { - s1 = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s1, substream) { if (s1 != substream) spin_unlock(&s1->self_group.lock); if (s1 == s) /* end */ @@ -1438,7 +1432,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) { struct snd_card *card; struct snd_pcm_runtime *runtime; - struct list_head *pos; + struct snd_pcm_substream *s; int result = 0; int i, num_drecs; struct drain_rec *drec, drec_tmp, *d; @@ -1473,8 +1467,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream) /* count only playback streams */ num_drecs = 0; - snd_pcm_group_for_each(pos, substream) { - struct snd_pcm_substream *s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { runtime = s->runtime; if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { d = &drec[num_drecs++]; @@ -1674,7 +1667,7 @@ static void relink_to_local(struct snd_pcm_substream *substream) static int snd_pcm_unlink(struct snd_pcm_substream *substream) { - struct list_head *pos; + struct snd_pcm_substream *s; int res = 0; down_write(&snd_pcm_link_rwsem); @@ -1686,8 +1679,8 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream) list_del(&substream->link_list); substream->group->count--; if (substream->group->count == 1) { /* detach the last stream, too */ - snd_pcm_group_for_each(pos, substream) { - relink_to_local(snd_pcm_group_substream_entry(pos)); + snd_pcm_group_for_each_entry(s, substream) { + relink_to_local(s); break; } kfree(substream->group); diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c index 75c7c5f..914d77b 100644 --- a/sound/isa/cs423x/cs4231_lib.c +++ b/sound/isa/cs423x/cs4231_lib.c @@ -405,7 +405,6 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, struct snd_cs4231 *chip = snd_pcm_substream_chip(substream); int result = 0; unsigned int what; - struct list_head *pos; struct snd_pcm_substream *s; int do_start; @@ -425,8 +424,7 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, } what = 0; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == chip->playback_substream) { what |= CS4231_PLAYBACK_ENABLE; snd_pcm_trigger_done(s, substream); diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 1c39058..95d0ab1 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -934,10 +934,8 @@ static int snd_opti93x_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_STOP: { unsigned int what = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == chip->playback_substream) { what |= OPTi93X_PLAYBACK_ENABLE; snd_pcm_trigger_done(s, substream); diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index ba7fa22..cd2fe37 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -1224,7 +1224,6 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, { struct snd_ali *codec = snd_pcm_substream_chip(substream); - struct list_head *pos; struct snd_pcm_substream *s; unsigned int what, whati, capture_flag; struct snd_ali_voice *pvoice = NULL, *evoice = NULL; @@ -1243,8 +1242,7 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, } what = whati = capture_flag = 0; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) { pvoice = s->runtime->private_data; evoice = pvoice->extra; diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index ea6712b..48f3f17 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -775,7 +775,6 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream, struct snd_ca0106_pcm *epcm; int channel; int result = 0; - struct list_head *pos; struct snd_pcm_substream *s; u32 basic = 0; u32 extended = 0; @@ -790,8 +789,7 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream, running=0; break; } - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { runtime = s->runtime; epcm = runtime->private_data; channel = epcm->channel_id; diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index e413da0..f27b6a7 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -705,11 +705,9 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct audiopipe *pipe = runtime->private_data; int i, err; u32 channelmask = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { for (i = 0; i < DSP_MAXPIPES; i++) { if (s == chip->substream[i]) { channelmask |= 1 << i; diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 465f8d5..7ee19c6 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -433,7 +433,6 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, struct snd_emu10k1_pcm *epcm; int channel; int result = 0; - struct list_head *pos; struct snd_pcm_substream *s; u32 basic = 0; u32 inte = 0; @@ -448,8 +447,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, running = 0; break; } - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { runtime = s->runtime; epcm = runtime->private_data; channel = substream->pcm->device-emu->p16v_device_offset; diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 425b167..6a0ddcf 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -798,10 +798,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: { unsigned int what = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == ensoniq->playback1_substream) { what |= ES_P1_PAUSE; snd_pcm_trigger_done(s, substream); @@ -824,10 +822,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: { unsigned int what = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == ensoniq->playback1_substream) { what |= ES_DAC1_EN; snd_pcm_trigger_done(s, substream); diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 830a1bb..e880469 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -977,11 +977,9 @@ static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream, { unsigned int what = 0; unsigned int old; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == ice->playback_pro_substream) { what |= ICE1712_PLAYBACK_START; snd_pcm_trigger_done(s, substream); diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 1127ebd..3f2aca2 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -337,13 +337,11 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); unsigned char what; unsigned char old; - struct list_head *pos; struct snd_pcm_substream *s; what = 0; - snd_pcm_group_for_each(pos, substream) { + snd_pcm_group_for_each_entry(s, substream) { const struct vt1724_pcm_reg *reg; - s = snd_pcm_group_substream_entry(pos); reg = s->runtime->private_data; what |= reg->start; snd_pcm_trigger_done(s, substream); diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index d974134..e1bdeed 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -638,7 +638,6 @@ static void pcxhr_trigger_tasklet(unsigned long arg) static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) { struct pcxhr_stream *stream; - struct list_head *pos; struct snd_pcm_substream *s; int i; @@ -646,8 +645,7 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) case SNDRV_PCM_TRIGGER_START: snd_printdd("SNDRV_PCM_TRIGGER_START\n"); i = 0; - snd_pcm_group_for_each(pos, subs) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, subs) { stream = s->runtime->private_data; stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN; snd_pcm_trigger_done(s, subs); @@ -672,8 +670,7 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) break; case SNDRV_PCM_TRIGGER_STOP: snd_printdd("SNDRV_PCM_TRIGGER_STOP\n"); - snd_pcm_group_for_each(pos, subs) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, subs) { stream = s->runtime->private_data; stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP; if (pcxhr_set_stream_state(stream)) diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 6bb7ac6..618653e 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -1078,12 +1078,10 @@ static int snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct rme32 *rme32 = snd_pcm_substream_chip(substream); - struct list_head *pos; struct snd_pcm_substream *s; spin_lock(&rme32->lock); - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s != rme32->playback_substream && s != rme32->capture_substream) continue; @@ -1110,8 +1108,7 @@ snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd) /* prefill playback buffer */ if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) { - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == rme32->playback_substream) { s->ops->ack(s); break; diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 89b3c7f..6540037 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -3780,11 +3780,9 @@ static int snd_hdsp_reset(struct snd_pcm_substream *substream) else runtime->status->hw_ptr = 0; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; struct snd_pcm_runtime *oruntime = other->runtime; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { oruntime->status->hw_ptr = runtime->status->hw_ptr; break; @@ -3933,10 +3931,8 @@ static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd) other = hdsp->playback_substream; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { snd_pcm_trigger_done(s, substream); if (cmd == SNDRV_PCM_TRIGGER_START) diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 6e95857..d2ae638 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -3575,11 +3575,9 @@ static int snd_hdspm_reset(struct snd_pcm_substream *substream) else runtime->status->hw_ptr = 0; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; struct snd_pcm_runtime *oruntime = other->runtime; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { oruntime->status->hw_ptr = runtime->status->hw_ptr; @@ -3791,10 +3789,8 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd) other = hdspm->playback_substream; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { snd_pcm_trigger_done(s, substream); if (cmd == SNDRV_PCM_TRIGGER_START) diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index cc3bdec..bd7dbd2 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -1992,11 +1992,9 @@ static int snd_rme9652_reset(struct snd_pcm_substream *substream) else runtime->status->hw_ptr = 0; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; struct snd_pcm_runtime *oruntime = other->runtime; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { oruntime->status->hw_ptr = runtime->status->hw_ptr; break; @@ -2140,10 +2138,8 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream, other = rme9652->playback_substream; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { snd_pcm_trigger_done(s, substream); if (cmd == SNDRV_PCM_TRIGGER_START) diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 3bff321..7ca6062 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -1540,7 +1540,6 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream, { struct snd_trident *trident = snd_pcm_substream_chip(substream); - struct list_head *pos; struct snd_pcm_substream *s; unsigned int what, whati, capture_flag, spdif_flag; struct snd_trident_voice *voice, *evoice; @@ -1563,8 +1562,7 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream, what = whati = capture_flag = spdif_flag = 0; spin_lock(&trident->reg_lock); val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) { voice = s->runtime->private_data; evoice = voice->extra; diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 900a00d..96d51ab 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -661,10 +661,9 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd) { unsigned int what = 0; struct snd_pcm_substream *s; - struct list_head *pos; unsigned long flags; - snd_pcm_group_for_each(pos, substream) { + snd_pcm_group_for_each_entry(s, substream) { s = snd_pcm_group_substream_entry(pos); if (s == chip->playback_substream) { what |= CS4231_PLAYBACK_ENABLE; -- cgit v0.10.2 From ac519028a4e7b919eaff65a1535824259df326c6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 22 Feb 2007 12:58:27 +0100 Subject: [ALSA] ac97 - Make patch functions static Include ac97_patch.c from the main ac97_codec.c in order to make bunch of patch_*() functions static. This helps optimization. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index 3c32221..f5d4718 100644 --- a/sound/pci/ac97/Makefile +++ b/sound/pci/ac97/Makefile @@ -3,7 +3,7 @@ # Copyright (c) 2001 by Jaroslav Kysela # -snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_patch.o +snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ifneq ($(CONFIG_PROC_FS),) snd-ac97-codec-objs += ac97_proc.o diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 3bfb210..bbed644 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -35,9 +35,9 @@ #include #include #include -#include "ac97_local.h" #include "ac97_id.h" -#include "ac97_patch.h" + +#include "ac97_patch.c" MODULE_AUTHOR("Jaroslav Kysela "); MODULE_DESCRIPTION("Universal interface for Audio Codec '97"); @@ -432,7 +432,8 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns * Controls */ -int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; @@ -446,7 +447,8 @@ int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem return 0; } -int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; @@ -462,7 +464,8 @@ int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ return 0; } -int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; @@ -508,7 +511,8 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save) } /* volume and switch controls */ -int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { int mask = (kcontrol->private_value >> 16) & 0xff; int shift = (kcontrol->private_value >> 8) & 0x0f; @@ -521,7 +525,8 @@ int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info return 0; } -int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value & 0xff; @@ -544,7 +549,8 @@ int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value return 0; } -int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value & 0xff; @@ -646,7 +652,7 @@ AC97_ENUM("Mic Select", std_enum[3]), AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0) }; -const struct snd_kcontrol_new snd_ac97_controls_3d[2] = { +static const struct snd_kcontrol_new snd_ac97_controls_3d[2] = { AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0), AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0) }; @@ -817,7 +823,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ return change; } -const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = { +static const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = { { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1097,7 +1103,7 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha } } -int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit) +static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit) { unsigned short mask, val, orig, res; @@ -1137,7 +1143,8 @@ static inline int printable(unsigned int x) return x; } -struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97) +static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, + struct snd_ac97 * ac97) { struct snd_kcontrol_new template; memcpy(&template, _template, sizeof(template)); @@ -2544,7 +2551,8 @@ static void set_ctl_name(char *dst, const char *src, const char *suffix) } /* remove the control with the given name and optional suffix */ -int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix) +static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, + const char *suffix) { struct snd_ctl_elem_id id; memset(&id, 0, sizeof(id)); @@ -2563,7 +2571,8 @@ static struct snd_kcontrol *ctl_find(struct snd_ac97 *ac97, const char *name, co } /* rename the control with the given name and optional suffix */ -int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix) +static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst, const char *suffix) { struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix); if (kctl) { @@ -2574,14 +2583,16 @@ int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, } /* rename both Volume and Switch controls - don't check the return value */ -void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst) +static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst) { snd_ac97_rename_ctl(ac97, src, dst, "Switch"); snd_ac97_rename_ctl(ac97, src, dst, "Volume"); } /* swap controls */ -int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix) +static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, + const char *s2, const char *suffix) { struct snd_kcontrol *kctl1, *kctl2; kctl1 = ctl_find(ac97, s1, suffix); diff --git a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h index a6244c7..78745c5 100644 --- a/sound/pci/ac97/ac97_local.h +++ b/sound/pci/ac97/ac97_local.h @@ -22,59 +22,8 @@ * */ -#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24)) -#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26)) -#define AC97_SINGLE(xname, reg, shift, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \ - .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ - .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) } -#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \ - .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ - .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) } -#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \ - .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ - .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) } - -/* enum control */ -struct ac97_enum { - unsigned char reg; - unsigned char shift_l; - unsigned char shift_r; - unsigned short mask; - const char **texts; -}; - -#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ -{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ - .mask = xmask, .texts = xtexts } -#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \ - AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts) -#define AC97_ENUM(xname, xenum) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_enum_double, \ - .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \ - .private_value = (unsigned long)&xenum } - -/* ac97_codec.c */ -extern const struct snd_kcontrol_new snd_ac97_controls_3d[]; -extern const struct snd_kcontrol_new snd_ac97_controls_spdif[]; -struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97); -void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem); -int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); -int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit); -int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix); -int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix); -int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix); -void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst); -void snd_ac97_restore_status(struct snd_ac97 *ac97); -void snd_ac97_restore_iec958(struct snd_ac97 *ac97); -int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); -int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); - +void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, + int modem); int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value); diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index b188a4d..30064c1 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -23,20 +23,8 @@ * */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "ac97_patch.h" -#include "ac97_id.h" #include "ac97_local.h" +#include "ac97_patch.h" /* * Chip specific initialization @@ -390,7 +378,7 @@ static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { .build_post_spdif = patch_yamaha_ymf753_post_spdif }; -int patch_yamaha_ymf753(struct snd_ac97 * ac97) +static int patch_yamaha_ymf753(struct snd_ac97 * ac97) { /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com. This chip has nonstandard and extended behaviour with regard to its S/PDIF output. @@ -436,7 +424,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { .build_specific = patch_wolfson_wm9703_specific, }; -int patch_wolfson03(struct snd_ac97 * ac97) +static int patch_wolfson03(struct snd_ac97 * ac97) { ac97->build_ops = &patch_wolfson_wm9703_ops; return 0; @@ -467,7 +455,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { .build_specific = patch_wolfson_wm9704_specific, }; -int patch_wolfson04(struct snd_ac97 * ac97) +static int patch_wolfson04(struct snd_ac97 * ac97) { /* WM9704M/9704Q */ ac97->build_ops = &patch_wolfson_wm9704_ops; @@ -489,7 +477,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = { .build_specific = patch_wolfson_wm9705_specific, }; -int patch_wolfson05(struct snd_ac97 * ac97) +static int patch_wolfson05(struct snd_ac97 * ac97) { /* WM9705, WM9710 */ ac97->build_ops = &patch_wolfson_wm9705_ops; @@ -625,7 +613,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { .build_specific = patch_wolfson_wm9711_specific, }; -int patch_wolfson11(struct snd_ac97 * ac97) +static int patch_wolfson11(struct snd_ac97 * ac97) { /* WM9711, WM9712 */ ac97->build_ops = &patch_wolfson_wm9711_ops; @@ -824,7 +812,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { #endif }; -int patch_wolfson13(struct snd_ac97 * ac97) +static int patch_wolfson13(struct snd_ac97 * ac97) { /* WM9713, WM9714 */ ac97->build_ops = &patch_wolfson_wm9713_ops; @@ -844,7 +832,7 @@ int patch_wolfson13(struct snd_ac97 * ac97) /* * Tritech codec */ -int patch_tritech_tr28028(struct snd_ac97 * ac97) +static int patch_tritech_tr28028(struct snd_ac97 * ac97) { snd_ac97_write_cache(ac97, 0x26, 0x0300); snd_ac97_write_cache(ac97, 0x26, 0x0000); @@ -922,7 +910,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { .build_specific = patch_sigmatel_stac97xx_specific }; -int patch_sigmatel_stac9700(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9700(struct snd_ac97 * ac97) { ac97->build_ops = &patch_sigmatel_stac9700_ops; return 0; @@ -969,7 +957,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { .build_specific = patch_sigmatel_stac9708_specific }; -int patch_sigmatel_stac9708(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9708(struct snd_ac97 * ac97) { unsigned int codec72, codec6c; @@ -995,7 +983,7 @@ int patch_sigmatel_stac9708(struct snd_ac97 * ac97) return 0; } -int patch_sigmatel_stac9721(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9721(struct snd_ac97 * ac97) { ac97->build_ops = &patch_sigmatel_stac9700_ops; if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) { @@ -1009,7 +997,7 @@ int patch_sigmatel_stac9721(struct snd_ac97 * ac97) return 0; } -int patch_sigmatel_stac9744(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9744(struct snd_ac97 * ac97) { // patch for SigmaTel ac97->build_ops = &patch_sigmatel_stac9700_ops; @@ -1021,7 +1009,7 @@ int patch_sigmatel_stac9744(struct snd_ac97 * ac97) return 0; } -int patch_sigmatel_stac9756(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9756(struct snd_ac97 * ac97) { // patch for SigmaTel ac97->build_ops = &patch_sigmatel_stac9700_ops; @@ -1198,7 +1186,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { .build_specific = patch_sigmatel_stac9758_specific }; -int patch_sigmatel_stac9758(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9758(struct snd_ac97 * ac97) { static unsigned short regs[4] = { AC97_SIGMATEL_OUTSEL, @@ -1272,7 +1260,7 @@ static struct snd_ac97_build_ops patch_cirrus_ops = { .build_spdif = patch_cirrus_build_spdif }; -int patch_cirrus_spdif(struct snd_ac97 * ac97) +static int patch_cirrus_spdif(struct snd_ac97 * ac97) { /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers. WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh* @@ -1293,7 +1281,7 @@ int patch_cirrus_spdif(struct snd_ac97 * ac97) return 0; } -int patch_cirrus_cs4299(struct snd_ac97 * ac97) +static int patch_cirrus_cs4299(struct snd_ac97 * ac97) { /* force the detection of PC Beep */ ac97->flags |= AC97_HAS_PC_BEEP; @@ -1329,7 +1317,7 @@ static struct snd_ac97_build_ops patch_conexant_ops = { .build_spdif = patch_conexant_build_spdif }; -int patch_conexant(struct snd_ac97 * ac97) +static int patch_conexant(struct snd_ac97 * ac97) { ac97->build_ops = &patch_conexant_ops; ac97->flags |= AC97_CX_SPDIF; @@ -1338,7 +1326,7 @@ int patch_conexant(struct snd_ac97 * ac97) return 0; } -int patch_cx20551(struct snd_ac97 *ac97) +static int patch_cx20551(struct snd_ac97 *ac97) { snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01); return 0; @@ -1430,7 +1418,7 @@ static const struct snd_ac97_res_table ad1819_restbl[] = { { } /* terminator */ }; -int patch_ad1819(struct snd_ac97 * ac97) +static int patch_ad1819(struct snd_ac97 * ac97) { unsigned short scfg; @@ -1507,7 +1495,7 @@ static struct snd_ac97_build_ops patch_ad1881_build_ops = { #endif }; -int patch_ad1881(struct snd_ac97 * ac97) +static int patch_ad1881(struct snd_ac97 * ac97) { static const char cfg_idxs[3][2] = { {2, 1}, @@ -1595,7 +1583,7 @@ static struct snd_ac97_build_ops patch_ad1885_build_ops = { #endif }; -int patch_ad1885(struct snd_ac97 * ac97) +static int patch_ad1885(struct snd_ac97 * ac97) { patch_ad1881(ac97); /* This is required to deal with the Intel D815EEAL2 */ @@ -1622,7 +1610,7 @@ static struct snd_ac97_build_ops patch_ad1886_build_ops = { #endif }; -int patch_ad1886(struct snd_ac97 * ac97) +static int patch_ad1886(struct snd_ac97 * ac97) { patch_ad1881(ac97); /* Presario700 workaround */ @@ -1844,7 +1832,7 @@ static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97) snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); } -int patch_ad1981a(struct snd_ac97 *ac97) +static int patch_ad1981a(struct snd_ac97 *ac97) { patch_ad1881(ac97); ac97->build_ops = &patch_ad1981a_build_ops; @@ -1877,7 +1865,7 @@ static struct snd_ac97_build_ops patch_ad1981b_build_ops = { #endif }; -int patch_ad1981b(struct snd_ac97 *ac97) +static int patch_ad1981b(struct snd_ac97 *ac97) { patch_ad1881(ac97); ac97->build_ops = &patch_ad1981b_build_ops; @@ -2014,7 +2002,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = { .update_jacks = ad1888_update_jacks, }; -int patch_ad1888(struct snd_ac97 * ac97) +static int patch_ad1888(struct snd_ac97 * ac97) { unsigned short misc; @@ -2052,7 +2040,7 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = { .update_jacks = ad1888_update_jacks, }; -int patch_ad1980(struct snd_ac97 * ac97) +static int patch_ad1980(struct snd_ac97 * ac97) { patch_ad1888(ac97); ac97->build_ops = &patch_ad1980_build_ops; @@ -2168,7 +2156,7 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = { .update_jacks = ad1985_update_jacks, }; -int patch_ad1985(struct snd_ac97 * ac97) +static int patch_ad1985(struct snd_ac97 * ac97) { unsigned short misc; @@ -2468,7 +2456,7 @@ static struct snd_ac97_build_ops patch_ad1986_build_ops = { .update_jacks = ad1986_update_jacks, }; -int patch_ad1986(struct snd_ac97 * ac97) +static int patch_ad1986(struct snd_ac97 * ac97) { patch_ad1881(ac97); ac97->build_ops = &patch_ad1986_build_ops; @@ -2561,7 +2549,7 @@ static struct snd_ac97_build_ops patch_alc650_ops = { .update_jacks = alc650_update_jacks }; -int patch_alc650(struct snd_ac97 * ac97) +static int patch_alc650(struct snd_ac97 * ac97) { unsigned short val; @@ -2713,7 +2701,7 @@ static struct snd_ac97_build_ops patch_alc655_ops = { .update_jacks = alc655_update_jacks }; -int patch_alc655(struct snd_ac97 * ac97) +static int patch_alc655(struct snd_ac97 * ac97) { unsigned int val; @@ -2815,7 +2803,7 @@ static struct snd_ac97_build_ops patch_alc850_ops = { .update_jacks = alc850_update_jacks }; -int patch_alc850(struct snd_ac97 *ac97) +static int patch_alc850(struct snd_ac97 *ac97) { ac97->build_ops = &patch_alc850_ops; @@ -2875,7 +2863,7 @@ static struct snd_ac97_build_ops patch_cm9738_ops = { .update_jacks = cm9738_update_jacks }; -int patch_cm9738(struct snd_ac97 * ac97) +static int patch_cm9738(struct snd_ac97 * ac97) { ac97->build_ops = &patch_cm9738_ops; /* FIXME: can anyone confirm below? */ @@ -2967,7 +2955,7 @@ static struct snd_ac97_build_ops patch_cm9739_ops = { .update_jacks = cm9739_update_jacks }; -int patch_cm9739(struct snd_ac97 * ac97) +static int patch_cm9739(struct snd_ac97 * ac97) { unsigned short val; @@ -3141,7 +3129,7 @@ static struct snd_ac97_build_ops patch_cm9761_ops = { .update_jacks = cm9761_update_jacks }; -int patch_cm9761(struct snd_ac97 *ac97) +static int patch_cm9761(struct snd_ac97 *ac97) { unsigned short val; @@ -3236,7 +3224,7 @@ static struct snd_ac97_build_ops patch_cm9780_ops = { .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ }; -int patch_cm9780(struct snd_ac97 *ac97) +static int patch_cm9780(struct snd_ac97 *ac97) { unsigned short val; @@ -3279,7 +3267,7 @@ static struct snd_ac97_build_ops patch_vt1616_ops = { .build_specific = patch_vt1616_specific }; -int patch_vt1616(struct snd_ac97 * ac97) +static int patch_vt1616(struct snd_ac97 * ac97) { ac97->build_ops = &patch_vt1616_ops; return 0; @@ -3288,7 +3276,7 @@ int patch_vt1616(struct snd_ac97 * ac97) /* * VT1617A codec */ -int patch_vt1617a(struct snd_ac97 * ac97) +static int patch_vt1617a(struct snd_ac97 * ac97) { /* bring analog power consumption to normal, like WinXP driver * for EPIA SP @@ -3338,7 +3326,7 @@ static struct snd_ac97_build_ops patch_it2646_ops = { .update_jacks = it2646_update_jacks }; -int patch_it2646(struct snd_ac97 * ac97) +static int patch_it2646(struct snd_ac97 * ac97) { ac97->build_ops = &patch_it2646_ops; /* full DAC volume */ @@ -3371,7 +3359,7 @@ static struct snd_ac97_build_ops patch_si3036_ops = { .build_specific = patch_si3036_specific, }; -int mpatch_si3036(struct snd_ac97 * ac97) +static int mpatch_si3036(struct snd_ac97 * ac97) { ac97->build_ops = &patch_si3036_ops; snd_ac97_write_cache(ac97, 0x5c, 0xf210 ); @@ -3403,7 +3391,7 @@ static struct snd_ac97_res_table lm4550_restbl[] = { { } /* terminator */ }; -int patch_lm4550(struct snd_ac97 *ac97) +static int patch_lm4550(struct snd_ac97 *ac97) { ac97->res_table = lm4550_restbl; return 0; @@ -3438,7 +3426,7 @@ static struct snd_ac97_build_ops patch_ucb1400_ops = { .build_specific = patch_ucb1400_specific, }; -int patch_ucb1400(struct snd_ac97 * ac97) +static int patch_ucb1400(struct snd_ac97 * ac97) { ac97->build_ops = &patch_ucb1400_ops; /* enable headphone driver and smart low power mode by default */ diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 555d1c9..fd341ce 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h @@ -22,44 +22,72 @@ * */ -int patch_yamaha_ymf753(struct snd_ac97 * ac97); -int patch_wolfson00(struct snd_ac97 * ac97); -int patch_wolfson03(struct snd_ac97 * ac97); -int patch_wolfson04(struct snd_ac97 * ac97); -int patch_wolfson05(struct snd_ac97 * ac97); -int patch_wolfson11(struct snd_ac97 * ac97); -int patch_wolfson13(struct snd_ac97 * ac97); -int patch_tritech_tr28028(struct snd_ac97 * ac97); -int patch_sigmatel_stac9700(struct snd_ac97 * ac97); -int patch_sigmatel_stac9708(struct snd_ac97 * ac97); -int patch_sigmatel_stac9721(struct snd_ac97 * ac97); -int patch_sigmatel_stac9744(struct snd_ac97 * ac97); -int patch_sigmatel_stac9756(struct snd_ac97 * ac97); -int patch_sigmatel_stac9758(struct snd_ac97 * ac97); -int patch_cirrus_cs4299(struct snd_ac97 * ac97); -int patch_cirrus_spdif(struct snd_ac97 * ac97); -int patch_conexant(struct snd_ac97 * ac97); -int patch_cx20551(struct snd_ac97 * ac97); -int patch_ad1819(struct snd_ac97 * ac97); -int patch_ad1881(struct snd_ac97 * ac97); -int patch_ad1885(struct snd_ac97 * ac97); -int patch_ad1886(struct snd_ac97 * ac97); -int patch_ad1888(struct snd_ac97 * ac97); -int patch_ad1980(struct snd_ac97 * ac97); -int patch_ad1981a(struct snd_ac97 * ac97); -int patch_ad1981b(struct snd_ac97 * ac97); -int patch_ad1985(struct snd_ac97 * ac97); -int patch_ad1986(struct snd_ac97 * ac97); -int patch_alc650(struct snd_ac97 * ac97); -int patch_alc655(struct snd_ac97 * ac97); -int patch_alc850(struct snd_ac97 * ac97); -int patch_cm9738(struct snd_ac97 * ac97); -int patch_cm9739(struct snd_ac97 * ac97); -int patch_cm9761(struct snd_ac97 * ac97); -int patch_cm9780(struct snd_ac97 * ac97); -int patch_vt1616(struct snd_ac97 * ac97); -int patch_vt1617a(struct snd_ac97 * ac97); -int patch_it2646(struct snd_ac97 * ac97); -int patch_ucb1400(struct snd_ac97 * ac97); -int mpatch_si3036(struct snd_ac97 * ac97); -int patch_lm4550(struct snd_ac97 * ac97); +#define AC97_SINGLE_VALUE(reg,shift,mask,invert) \ + ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \ + ((invert) << 24)) +#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \ + (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26)) +#define AC97_SINGLE(xname, reg, shift, mask, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_ac97_info_volsw, \ + .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ + .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) } +#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_ac97_info_volsw, \ + .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ + .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) } +#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .info = snd_ac97_info_volsw, \ + .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ + .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) } + +/* enum control */ +struct ac97_enum { + unsigned char reg; + unsigned char shift_l; + unsigned char shift_r; + unsigned short mask; + const char **texts; +}; + +#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ +{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ + .mask = xmask, .texts = xtexts } +#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \ + AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts) +#define AC97_ENUM(xname, xenum) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_ac97_info_enum_double, \ + .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \ + .private_value = (unsigned long)&xenum } + +/* ac97_codec.c */ +static const struct snd_kcontrol_new snd_ac97_controls_3d[]; +static const struct snd_kcontrol_new snd_ac97_controls_spdif[]; +static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, + struct snd_ac97 * ac97); +static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit); +static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, + const char *suffix); +static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst, const char *suffix); +static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, + const char *s2, const char *suffix); +static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst); +static void snd_ac97_restore_status(struct snd_ac97 *ac97); +static void snd_ac97_restore_iec958(struct snd_ac97 *ac97); +static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c index 3758d07..4281e6d 100644 --- a/sound/pci/ac97/ac97_pcm.c +++ b/sound/pci/ac97/ac97_pcm.c @@ -34,7 +34,6 @@ #include #include #include -#include "ac97_patch.h" #include "ac97_id.h" #include "ac97_local.h" -- cgit v0.10.2 From 62e96a1caab86e0d3688d59fcb6f682cc52d4917 Mon Sep 17 00:00:00 2001 From: vignesh babu Date: Thu, 22 Feb 2007 13:23:01 +0100 Subject: [ALSA] is_power_of_2 in rtctimer.c Replacing (n & (n-1)) in the context of power of 2 checks with is_power_of_2 Signed-off-by: vignesh babu Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c index 9f7b32e..7cd5e8f 100644 --- a/sound/core/rtctimer.c +++ b/sound/core/rtctimer.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -129,7 +130,7 @@ static int __init rtctimer_init(void) struct snd_timer *timer; if (rtctimer_freq < 2 || rtctimer_freq > 8192 || - (rtctimer_freq & (rtctimer_freq - 1)) != 0) { + !is_power_of_2(rtctimer_freq)) { snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq); return -EINVAL; -- cgit v0.10.2 From 76e630677419ecf2cf8c0b738536eee34dc048e6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 22 Feb 2007 13:31:08 +0100 Subject: [ALSA] bt87x - Add ATI TV-Wonder to the supported list Added ATI TV-Wonder (1002:0001) to the supported list. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index e9b029e..9eb95a2 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = { BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), /* Viewcast Osprey 200 */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), + /* ATI TV-Wonder */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000), /* Leadtek Winfast tv 2000xp delux */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), /* Voodoo TV 200 */ -- cgit v0.10.2 From 8f7ba051d2abb3d3bde9b95e47246c60b704d2b4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 22 Feb 2007 16:07:21 +0100 Subject: [ALSA] mpu401 - Add MPU401_INFO_UART_ONLY bitflag Added MPU401_INFO_UART_ONLY bitflag to avoid issueing UART_ENTER command at opening streams. Some devices support only UART mode and give errors to UART_ENTER. A new module option, uart_enter, is added to snd-mpu401 driver. For UART-only devices, set uart_enter=0. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 73e9a17..24ea129 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1278,6 +1278,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. port - port number or -1 (disable) irq - IRQ number or -1 (disable) pnp - PnP detection - 0 = disable, 1 = enable (default) + uart_enter - Issue UART_ENTER command at open - bool, default = on This module supports multiple devices and PnP. diff --git a/include/sound/mpu401.h b/include/sound/mpu401.h index 8c88267..d5c1396 100644 --- a/include/sound/mpu401.h +++ b/include/sound/mpu401.h @@ -50,6 +50,7 @@ #define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */ #define MPU401_INFO_MMIO (1 << 3) /* MMIO access */ #define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */ +#define MPU401_INFO_UART_ONLY (1 << 5) /* No ENTER_UART cmd needed */ #define MPU401_MODE_BIT_INPUT 0 #define MPU401_MODE_BIT_OUTPUT 1 diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 2de181a..1d563e5 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c @@ -42,6 +42,7 @@ static int pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */ +static int uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for MPU-401 device."); @@ -57,6 +58,8 @@ module_param_array(port, long, NULL, 0444); MODULE_PARM_DESC(port, "Port # for MPU-401 device."); module_param_array(irq, int, NULL, 0444); MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device."); +module_param_array(uart_enter, bool, NULL, 0444); +MODULE_PARM_DESC(uart_enter, "Issue UART_ENTER command at open."); static struct platform_device *platform_devices[SNDRV_CARDS]; static int pnp_registered; @@ -80,10 +83,11 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard) strcat(card->longname, "polled"); } - if ((err = snd_mpu401_uart_new(card, 0, - MPU401_HW_MPU401, - port[dev], 0, - irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, NULL)) < 0) { + err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], + uart_enter[dev] ? 0 : MPU401_INFO_UART_ONLY, + irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, + NULL); + if (err < 0) { printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]); goto _err; } diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index 3daa9fa..85aedc3 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c @@ -266,6 +266,16 @@ static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, return 0; } +static int snd_mpu401_do_reset(struct snd_mpu401 *mpu) +{ + if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) + return -EIO; + if (!(mpu->info_flags & MPU401_INFO_UART_ONLY) && + snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) + return -EIO; + return 0; +} + /* * input/output open/close - protected by open_mutex in rawmidi.c */ @@ -278,9 +288,7 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream) if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) return err; if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { - if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) - goto error_out; - if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) + if (snd_mpu401_do_reset(mpu) < 0) goto error_out; } mpu->substream_input = substream; @@ -302,9 +310,7 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream) if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) return err; if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { - if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) - goto error_out; - if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) + if (snd_mpu401_do_reset(mpu) < 0) goto error_out; } mpu->substream_output = substream; -- cgit v0.10.2 From 8ad2da1937168d48a84dcf6d5cc2001c0e4a6992 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 26 Feb 2007 15:55:43 +0100 Subject: [ALSA] Enable Kconfig options for external firmwares Some drivers are already ifdefs for enabling external firmwares but not defined in Kconfig. Now they appear as the kernel configs. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 4e3a972..c855e35 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -358,12 +358,21 @@ config SND_SBAWE config SND_SB16_CSP bool "Sound Blaster 16/AWE CSP support" depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) - select FW_LOADER help Say Y here to include support for the CSP core. This special coprocessor can do variable tasks like various compression and decompression algorithms. +config SND_SB16_CSP_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for SB16 CSP" + depends on SND_SB16_CSP + select FW_LOADER + default y + help + Say Y here to include the static firmware built in the kernel + for SB16 CSP controller. If you choose N here, the external + firmware files from alsa-plugins pacakge are necessary. + config SND_SGALAXY tristate "Aztech Sound Galaxy" depends on SND @@ -391,7 +400,6 @@ config SND_SSCAPE config SND_WAVEFRONT tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)" depends on SND - select FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART select SND_CS4231_LIB @@ -402,4 +410,14 @@ config SND_WAVEFRONT To compile this driver as a module, choose M here: the module will be called snd-wavefront. +config SND_WAVEFRONT_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for Wavefront" + depends on SND_WAVEFRONT + select FW_LOADER + default y + help + Say Y here to include the static firmware built in the kernel + for Wavefront driver. If you choose N here, the external + firmware files from alsa-plugins pacakge are necessary. + endmenu diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index 3d9d7e0..ef71e50 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c @@ -690,9 +690,7 @@ static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __use return err; } -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL #include "sb16_csp_codecs.h" static const struct firmware snd_sb_csp_static_programs[] = { @@ -724,7 +722,7 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags) if (err >= 0) p->csp_programs[index] = program; else { -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL program = &snd_sb_csp_static_programs[index]; #else return err; diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c index 15331ed..3a8c056 100644 --- a/sound/isa/wavefront/wavefront_fx.c +++ b/sound/isa/wavefront/wavefront_fx.c @@ -35,9 +35,7 @@ #define WAIT_IDLE 0xff -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL #include "yss225.c" static const struct firmware yss225_registers_firmware = { .data = (u8 *)yss225_registers, @@ -266,7 +264,7 @@ snd_wavefront_fx_start (snd_wavefront_t *dev) err = request_firmware(&firmware, "yamaha/yss225_registers.bin", dev->card->dev); if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL firmware = &yss225_registers_firmware; #else err = -1; @@ -295,7 +293,7 @@ snd_wavefront_fx_start (snd_wavefront_t *dev) err = 0; out: -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL if (firmware != &yss225_registers_firmware) #endif release_firmware(firmware); diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 1bcfb3a..12dfda3 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -576,7 +576,6 @@ config SND_INTEL8X0M config SND_KORG1212 tristate "Korg 1212 IO" depends on SND - select FW_LOADER select SND_PCM help Say Y here to include support for Korg 1212IO soundcards. @@ -584,6 +583,16 @@ config SND_KORG1212 To compile this driver as a module, choose M here: the module will be called snd-korg1212. +config SND_KORG1212_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for Korg1212 driver" + depends on SND_KORG1212 + select FW_LOADER + default y + help + Say Y here to include the static firmware built in the kernel + for Korg1212 driver. If you choose N here, the external + firmware files from alsa-plugins pacakge are necessary. + config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" depends on SND @@ -596,6 +605,16 @@ config SND_MAESTRO3 To compile this driver as a module, choose M here: the module will be called snd-maestro3. +config SND_MAESTRO3_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for Maestro3 driver" + depends on SND_MAESTRO3 + select FW_LOADER + default y + help + Say Y here to include the static firmware built in the kernel + for Maestro3 driver. If you choose N here, the external + firmware files from alsa-plugins pacakge are necessary. + config SND_MIXART tristate "Digigram miXart" depends on SND @@ -737,7 +756,6 @@ config SND_VX222 config SND_YMFPCI tristate "Yamaha YMF724/740/744/754" depends on SND - select FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC @@ -748,6 +766,16 @@ config SND_YMFPCI To compile this driver as a module, choose M here: the module will be called snd-ymfpci. +config SND_YMFPCI_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for YMFPCI driver" + depends on SND_YMFPCI + select FW_LOADER + default y + help + Say Y here to include the static firmware built in the kernel + for YMFPCI driver. If you choose N here, the external + firmware files from alsa-plugins pacakge are necessary. + config SND_AC97_POWER_SAVE bool "AC97 Power-Saving Mode" depends on SND_AC97_CODEC && EXPERIMENTAL diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 21d0899a..e2e59ca 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -264,9 +264,7 @@ enum MonitorModeSelector { #define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement // from the card after sending a command. -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL #include "korg1212-firmware.h" static const struct firmware static_dsp_code = { .data = (u8 *)dspCode, @@ -2345,7 +2343,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); if (err < 0) { release_firmware(dsp_code); -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL dsp_code = &static_dsp_code; #else snd_printk(KERN_ERR "firmware not available\n"); @@ -2358,7 +2356,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * dsp_code->size, &korg1212->dma_dsp) < 0) { snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size); snd_korg1212_free(korg1212); -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL if (dsp_code != &static_dsp_code) #endif release_firmware(dsp_code); @@ -2371,7 +2369,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size); -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL if (dsp_code != &static_dsp_code) #endif release_firmware(dsp_code); diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 4526904..9badbb3 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -2101,9 +2101,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) } -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL /* * DSP Code images @@ -2242,7 +2240,7 @@ static const struct firmware assp_minisrc = { .size = sizeof assp_minisrc_image }; -#endif /* FIRMWARE_IN_THE_KERNEL */ +#endif /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ #ifdef __LITTLE_ENDIAN static inline void snd_m3_convert_from_le(const struct firmware *fw) { } @@ -2550,11 +2548,11 @@ static int snd_m3_free(struct snd_m3 *chip) if (chip->iobase) pci_release_regions(chip->pci); -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL if (chip->assp_kernel_image != &assp_kernel) #endif release_firmware(chip->assp_kernel_image); -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL if (chip->assp_minisrc_image != &assp_minisrc) #endif release_firmware(chip->assp_minisrc_image); @@ -2750,7 +2748,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, err = request_firmware(&chip->assp_kernel_image, "ess/maestro3_assp_kernel.fw", &pci->dev); if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL chip->assp_kernel_image = &assp_kernel; #else snd_m3_free(chip); @@ -2762,7 +2760,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, err = request_firmware(&chip->assp_minisrc_image, "ess/maestro3_assp_minisrc.fw", &pci->dev); if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL chip->assp_minisrc_image = &assp_minisrc; #else snd_m3_free(chip); diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index fd12674..b34c3bc 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -1998,9 +1998,7 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip) } } -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL #include "ymfpci_image.h" @@ -2047,7 +2045,7 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) } } if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL chip->dsp_microcode = &snd_ymfpci_dsp_microcode; #else return err; @@ -2070,7 +2068,7 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) } } if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL chip->controller_microcode = is_1e ? &snd_ymfpci_controller_1e_microcode : &snd_ymfpci_controller_microcode; @@ -2259,11 +2257,11 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip) pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl); pci_disable_device(chip->pci); -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL if (chip->dsp_microcode != &snd_ymfpci_dsp_microcode) #endif release_firmware(chip->dsp_microcode); -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL if (chip->controller_microcode != &snd_ymfpci_controller_microcode && chip->controller_microcode != &snd_ymfpci_controller_1e_microcode) #endif -- cgit v0.10.2 From 6d7b1d7d09e00034325b09a3a7ac7b0ea5e29506 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 26 Feb 2007 15:56:46 +0100 Subject: [ALSA] hda-codec - Allow model=generic always for generic parser Accept model=generic option to specify the generic parser regardless of codec chips. This is helpful for testing and debugging. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 24ea129..4d92a3e6 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -924,6 +924,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. vaio Setup for VAIO FE550G/SZ110 vaio-ar Setup for VAIO AR + The model name "genric" is treated as a special case. When this + model is given, the driver uses the generic codec parser without + "codec-patch". It's sometimes good for testing and debugging. + If the default configuration doesn't work and one of the above matches with your device, report it together with the PCI subsystem ID (output of "lspci -nv") to ALSA BTS or alsa-devel diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 8f34fb4..4c0a6a5 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -573,7 +573,8 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 0); } - codec->preset = find_codec_preset(codec); + if (strcmp(codec->bus->modelname, "generic")) + codec->preset = find_codec_preset(codec); if (! *bus->card->mixername) snd_hda_get_codec_name(codec, bus->card->mixername, sizeof(bus->card->mixername)); -- cgit v0.10.2 From d5ad630b6dd00ea41e0c58b45c0912f72757b5cd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 7 Mar 2007 15:55:59 +0100 Subject: [ALSA] Fix NULL dereference with null modelname Fix the NULL dereference of modelname option. The check is moved to find_codec_preset() now, too. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 4c0a6a5..e768187 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -403,6 +403,9 @@ static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec) { const struct hda_codec_preset **tbl, *preset; + if (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic")) + return NULL; /* use the generic parser */ + for (tbl = hda_preset_tables; *tbl; tbl++) { for (preset = *tbl; preset->id; preset++) { u32 mask = preset->mask; @@ -573,8 +576,7 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 0); } - if (strcmp(codec->bus->modelname, "generic")) - codec->preset = find_codec_preset(codec); + codec->preset = find_codec_preset(codec); if (! *bus->card->mixername) snd_hda_get_codec_name(codec, bus->card->mixername, sizeof(bus->card->mixername)); -- cgit v0.10.2 From a43ae90543f4c5eccbc050eda088c07cf45b61c0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 7 Mar 2007 15:58:40 +0100 Subject: [ALSA] Fix compilation error in sparc/cs4231.c Removed the unnecessary line I forgot in the last clean-up patch wrt snd_pcm_group_for_each_entry(). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 96d51ab..dca0344 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -664,7 +664,6 @@ static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd) unsigned long flags; snd_pcm_group_for_each_entry(s, substream) { - s = snd_pcm_group_substream_entry(pos); if (s == chip->playback_substream) { what |= CS4231_PLAYBACK_ENABLE; snd_pcm_trigger_done(s, substream); -- cgit v0.10.2 From e378ad1dcb7f5cf6de4974832d01be04e112c4c2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 7 Mar 2007 16:23:50 +0100 Subject: [ALSA] aoa: fix a sparse warning This fixes a warning sparse gives. Signed-off-by: Johannes Berg Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c index 8b2e9b9..64d1639 100644 --- a/sound/aoa/soundbus/core.c +++ b/sound/aoa/soundbus/core.c @@ -163,8 +163,6 @@ static int soundbus_device_resume(struct device * dev) #endif /* CONFIG_PM */ -extern struct device_attribute soundbus_dev_attrs[]; - static struct bus_type soundbus_bus_type = { .name = "aoa-soundbus", .probe = soundbus_probe, diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h index 5c27297..622cd37 100644 --- a/sound/aoa/soundbus/soundbus.h +++ b/sound/aoa/soundbus/soundbus.h @@ -199,4 +199,6 @@ struct soundbus_driver { extern int soundbus_register_driver(struct soundbus_driver *drv); extern void soundbus_unregister_driver(struct soundbus_driver *drv); +extern struct device_attribute soundbus_dev_attrs[]; + #endif /* __SOUNDBUS_H */ -- cgit v0.10.2 From 59ae9d05918aca6790fece86b6b3f7daef66d6a8 Mon Sep 17 00:00:00 2001 From: Giuliano Pochini Date: Wed, 7 Mar 2007 18:20:59 +0100 Subject: [ALSA] echoaudio - increase sleep time at loading firmware The new ASIC code needs more time to set up. (Note: the driver still works fine with the old firmware after this change. The opposite is not true.) From: Giuliano Pochini Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c index 9f439ea..52a9331 100644 --- a/sound/pci/echoaudio/echoaudio_3g.c +++ b/sound/pci/echoaudio/echoaudio_3g.c @@ -233,8 +233,8 @@ static int load_asic(struct echoaudio *chip) chip->asic_code = &card_fw[FW_3G_ASIC]; - /* Now give the new ASIC a little time to set up */ - mdelay(2); + /* Now give the new ASIC some time to set up */ + msleep(1000); /* See if it worked */ box_type = check_asic_status(chip); -- cgit v0.10.2 From ffb2c3c07f6ffd61923de736139248b31dc6f642 Mon Sep 17 00:00:00 2001 From: Remy Bruno Date: Wed, 7 Mar 2007 19:08:46 +0100 Subject: [ALSA] hdspm - Support for Master mode of AES32 and recent MADI The current MADI driver was found not to completely work, at least on recent MADI cards (rev 204), in particular at 96kHz. This patch solves this: * Add support of DDS feature * Channel map fixed * Channel/rate rules fixed * DMA allocation fixed (need to alloc for all channels and not only for the used ones) Full support for AES32 master mode was added: * Add support of DDS feature * Channel map fixed * Channel/rate rules fixed Signed-off-by: Remy Bruno Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index d2ae638..143185e 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -91,8 +91,10 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_controlRegister 64 #define HDSPM_interruptConfirmation 96 #define HDSPM_control2Reg 256 /* not in specs ???????? */ +#define HDSPM_freqReg 256 /* for AES32 */ #define HDSPM_midiDataOut0 352 /* just believe in old code */ #define HDSPM_midiDataOut1 356 +#define HDSPM_eeprom_wr 384 /* for AES32 */ /* DMA enable for 64 channels, only Bit 0 is relevant */ #define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ @@ -389,9 +391,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); size is the same regardless of the number of channels, and also the latency to use. for one direction !!! - => need to mupltiply by 2!! */ -#define HDSPM_DMA_AREA_BYTES (2 * HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) +#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) /* revisions >= 230 indicate AES32 card */ @@ -484,28 +485,6 @@ static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = { 56, 57, 58, 59, 60, 61, 62, 63 }; -static char channel_map_madi_ds[HDSPM_MAX_CHANNELS] = { - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 -}; - -static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60 - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 -}; - static struct pci_device_id snd_hdspm_ids[] __devinitdata = { { @@ -818,6 +797,27 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames) return 0; } +static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) +{ + u64 n; + u32 r; + + if (rate >= 112000) + rate /= 4; + else if (rate >= 56000) + rate /= 2; + + /* RME says n = 104857600000000, but in the windows MADI driver, I see: +// return 104857600000000 / rate; // 100 MHz + return 110100480000000 / rate; // 105 MHz + */ + //n = 104857600000000ULL; /* = 2^20 * 10^8 */ + n = 110100480000000ULL; /* Value checked for AES32 and MADI */ + div64_32(&n, rate, &r); + /* n should be less than 2^32 for being written to FREQ register */ + snd_assert((n >> 32) == 0); + hdspm_write(hdspm, HDSPM_freqReg, (u32)n); +} /* dummy set rate lets see what happens */ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) @@ -943,12 +943,16 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) hdspm->control_register |= rate_bits; hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); - if (rate > 96000 /* 64000*/) - hdspm->channel_map = channel_map_madi_qs; - else if (rate > 48000) - hdspm->channel_map = channel_map_madi_ds; - else - hdspm->channel_map = channel_map_madi_ss; + /* For AES32, need to set DDS value in FREQ register + For MADI, also apparently */ + hdspm_set_dds_value(hdspm, rate); + + if (hdspm->is_aes32 && rate != current_rate) + hdspm_write(hdspm, HDSPM_eeprom_wr, 0); + + /* For AES32 and for MADI (at least rev 204), channel_map needs to + * always be channel_map_madi_ss, whatever the sample rate */ + hdspm->channel_map = channel_map_madi_ss; hdspm->system_sample_rate = rate; @@ -3184,8 +3188,8 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); snd_iprintf(buffer, - "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", - hdspm->control_register, hdspm->control2_register, + "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", + hdspm->control_register, status, status2, timecode); snd_iprintf(buffer, "--- Settings ---\n"); @@ -3377,13 +3381,16 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); + if (!hdspm->is_aes32) { + /* No control2 register for AES32 */ #ifdef SNDRV_BIG_ENDIAN - hdspm->control2_register = HDSPM_BIGENDIAN_MODE; + hdspm->control2_register = HDSPM_BIGENDIAN_MODE; #else - hdspm->control2_register = 0; + hdspm->control2_register = 0; #endif - hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register); + hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register); + } hdspm_compute_period_size(hdspm); /* silence everything */ @@ -3656,11 +3663,10 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, /* Memory allocation, takashi's method, dont know if we should spinlock */ /* malloc all buffer even if not enabled to get sure */ - /* malloc only needed bytes */ + /* Update for MADI rev 204: we need to allocate for all channels, + * otherwise it doesn't work at 96kHz */ err = - snd_pcm_lib_malloc_pages(substream, - HDSPM_CHANNEL_BUFFER_BYTES * - params_channels(params)); + snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES); if (err < 0) return err; @@ -3696,6 +3702,13 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, "playback" : "capture", snd_pcm_sgbuf_get_addr(sgbuf, 0)); */ + /* + snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", + substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + "playback" : "capture", + params_rate(params), params_channels(params), + params_buffer_size(params)); + */ return 0; } @@ -3900,16 +3913,16 @@ static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params, struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - if (r->min > 48000) { + if (r->min > 48000 && r->max <= 96000) { struct snd_interval t = { - .min = 1, + .min = hdspm->ds_channels, .max = hdspm->ds_channels, .integer = 1, }; return snd_interval_refine(c, &t); } else if (r->max < 64000) { struct snd_interval t = { - .min = 1, + .min = hdspm->ss_channels, .max = hdspm->ss_channels, .integer = 1, }; @@ -3927,14 +3940,14 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - if (c->min <= hdspm->ss_channels) { + if (c->min >= hdspm->ss_channels) { struct snd_interval t = { .min = 32000, .max = 48000, .integer = 1, }; return snd_interval_refine(r, &t); - } else if (c->max > hdspm->ss_channels) { + } else if (c->max <= hdspm->ds_channels) { struct snd_interval t = { .min = 64000, .max = 96000, @@ -3946,13 +3959,39 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, return 0; } +static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + unsigned int list[3]; + struct hdspm *hdspm = rule->private; + struct snd_interval *c = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + if (hdspm->is_aes32) { + list[0] = hdspm->qs_channels; + list[1] = hdspm->ds_channels; + list[2] = hdspm->ss_channels; + return snd_interval_list(c, 3, list, 0); + } else { + list[0] = hdspm->ds_channels; + list[1] = hdspm->ss_channels; + return snd_interval_list(c, 2, list, 0); + } +} + + +static unsigned int hdspm_aes32_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }; + +static struct snd_pcm_hw_constraint_list hdspm_hw_constraints_aes32_sample_rates = { + .count = ARRAY_SIZE(hdspm_aes32_sample_rates), + .list = hdspm_aes32_sample_rates, + .mask = 0 +}; + static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) { struct hdspm *hdspm = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - snd_printdd("Open device substream %d\n", substream->stream); - spin_lock_irq(&hdspm->lock); snd_pcm_set_sync(substream); @@ -3973,14 +4012,21 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes); - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - snd_hdspm_hw_rule_channels_rate, hdspm, - SNDRV_PCM_HW_PARAM_RATE, -1); - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - snd_hdspm_hw_rule_rate_channels, hdspm, - SNDRV_PCM_HW_PARAM_CHANNELS, -1); - + if (hdspm->is_aes32) { + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &hdspm_hw_constraints_aes32_sample_rates); + } else { + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels_rate, hdspm, + SNDRV_PCM_HW_PARAM_RATE, -1); + + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + snd_hdspm_hw_rule_rate_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + } return 0; } @@ -4020,14 +4066,21 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes); - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - snd_hdspm_hw_rule_channels_rate, hdspm, - SNDRV_PCM_HW_PARAM_RATE, -1); - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - snd_hdspm_hw_rule_rate_channels, hdspm, - SNDRV_PCM_HW_PARAM_CHANNELS, -1); + if (hdspm->is_aes32) { + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &hdspm_hw_constraints_aes32_sample_rates); + } else { + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels_rate, hdspm, + SNDRV_PCM_HW_PARAM_RATE, -1); + + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + snd_hdspm_hw_rule_rate_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + } return 0; } -- cgit v0.10.2 From 4d02031fe25c01eaa946a25e2052dd8e706edfca Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 8 Mar 2007 12:53:55 +0100 Subject: [ALSA] soc - Fix dependencies in s3c24xx/Kconfig Fixed dependencies in soc/s3c24xx/Kconfig file. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 433da9f..bb6e00a 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -2,8 +2,7 @@ menu "SoC Audio for the Samsung S3C24XX" config SND_S3C24XX_SOC tristate "SoC Audio for the Samsung S3C24XX chips" - depends on ARCH_S3C2410 && SND - select SND_PCM + depends on ARCH_S3C2410 && SND_SOC help Say Y or M if you want to add support for codecs attached to the S3C24XX AC97, I2S or SSP interface. You will also need -- cgit v0.10.2 From badec46ddf7c2d1cb0b944332746828c48debe40 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 12 Mar 2007 08:30:16 +0100 Subject: [ALSA] Kconfig: fix FW_LOADER dependencies Move the FW_LOADER dependencies out of the *_FIRMWARE_IN_KERNEL entries because these drivers use the firmware loader regardless of whether there is an in-kernel firmware image. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index c855e35..992e8c3 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -358,6 +358,7 @@ config SND_SBAWE config SND_SB16_CSP bool "Sound Blaster 16/AWE CSP support" depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) + select FW_LOADER help Say Y here to include support for the CSP core. This special coprocessor can do variable tasks like various compression and @@ -366,7 +367,6 @@ config SND_SB16_CSP config SND_SB16_CSP_FIRMWARE_IN_KERNEL bool "In-kernel firmware for SB16 CSP" depends on SND_SB16_CSP - select FW_LOADER default y help Say Y here to include the static firmware built in the kernel @@ -400,6 +400,7 @@ config SND_SSCAPE config SND_WAVEFRONT tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)" depends on SND + select FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART select SND_CS4231_LIB @@ -413,7 +414,6 @@ config SND_WAVEFRONT config SND_WAVEFRONT_FIRMWARE_IN_KERNEL bool "In-kernel firmware for Wavefront" depends on SND_WAVEFRONT - select FW_LOADER default y help Say Y here to include the static firmware built in the kernel diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 12dfda3..b8e6458 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -576,6 +576,7 @@ config SND_INTEL8X0M config SND_KORG1212 tristate "Korg 1212 IO" depends on SND + select FW_LOADER select SND_PCM help Say Y here to include support for Korg 1212IO soundcards. @@ -586,7 +587,6 @@ config SND_KORG1212 config SND_KORG1212_FIRMWARE_IN_KERNEL bool "In-kernel firmware for Korg1212 driver" depends on SND_KORG1212 - select FW_LOADER default y help Say Y here to include the static firmware built in the kernel @@ -608,7 +608,6 @@ config SND_MAESTRO3 config SND_MAESTRO3_FIRMWARE_IN_KERNEL bool "In-kernel firmware for Maestro3 driver" depends on SND_MAESTRO3 - select FW_LOADER default y help Say Y here to include the static firmware built in the kernel @@ -756,6 +755,7 @@ config SND_VX222 config SND_YMFPCI tristate "Yamaha YMF724/740/744/754" depends on SND + select FW_LOADER select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC @@ -769,7 +769,6 @@ config SND_YMFPCI config SND_YMFPCI_FIRMWARE_IN_KERNEL bool "In-kernel firmware for YMFPCI driver" depends on SND_YMFPCI - select FW_LOADER default y help Say Y here to include the static firmware built in the kernel -- cgit v0.10.2 From d65b790adbd8ea4b4c9687eda722d7b2a730ed02 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 12 Mar 2007 08:30:58 +0100 Subject: [ALSA] Kconfig: clarify help text for external firmware entries The external firmware files are not in the alsa-plugins but in the alsa-firmware package. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 992e8c3..376c6b0 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -370,8 +370,8 @@ config SND_SB16_CSP_FIRMWARE_IN_KERNEL default y help Say Y here to include the static firmware built in the kernel - for SB16 CSP controller. If you choose N here, the external - firmware files from alsa-plugins pacakge are necessary. + for the SB16 CSP controller. If you choose N here, you need + to install the firmware files from the alsa-firmware package. config SND_SGALAXY tristate "Aztech Sound Galaxy" @@ -417,7 +417,7 @@ config SND_WAVEFRONT_FIRMWARE_IN_KERNEL default y help Say Y here to include the static firmware built in the kernel - for Wavefront driver. If you choose N here, the external - firmware files from alsa-plugins pacakge are necessary. + for the Wavefront driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. endmenu diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index b8e6458..9ed4f2f 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -590,8 +590,8 @@ config SND_KORG1212_FIRMWARE_IN_KERNEL default y help Say Y here to include the static firmware built in the kernel - for Korg1212 driver. If you choose N here, the external - firmware files from alsa-plugins pacakge are necessary. + for the Korg1212 driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" @@ -611,8 +611,8 @@ config SND_MAESTRO3_FIRMWARE_IN_KERNEL default y help Say Y here to include the static firmware built in the kernel - for Maestro3 driver. If you choose N here, the external - firmware files from alsa-plugins pacakge are necessary. + for the Maestro3 driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. config SND_MIXART tristate "Digigram miXart" @@ -772,8 +772,8 @@ config SND_YMFPCI_FIRMWARE_IN_KERNEL default y help Say Y here to include the static firmware built in the kernel - for YMFPCI driver. If you choose N here, the external - firmware files from alsa-plugins pacakge are necessary. + for the YMFPCI driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. config SND_AC97_POWER_SAVE bool "AC97 Power-Saving Mode" -- cgit v0.10.2 From 592a82e8b6f4b5376e2faa2467b816cc8b73eaa6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 12 Mar 2007 11:33:32 +0100 Subject: [ALSA] ac97 - Fix MSI L720 laptop Fix internal speaker output of MSI L720 laptop with ALC655 codec. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 30064c1..43455fc 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -2727,6 +2727,7 @@ static int patch_alc655(struct snd_ac97 * ac97) (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */ ac97->subsystem_device == 0x0161 || /* LG K1 Express */ ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */ + ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */ ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */ val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ else -- cgit v0.10.2 From 68e22543eec3e44508d0d4ed584562478b942b09 Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Mon, 12 Mar 2007 11:36:39 +0100 Subject: [ALSA] hda-codec - Add Sony VGC-LA1 to patch_sigmatel.c This patch adds the Sony Vaio VGC-LA1 to the stac9872_cfg_tbl. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c94291b..fef56ef 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2294,6 +2294,7 @@ static struct snd_pci_quirk stac9872_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO), SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO), SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO), + SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO), {} }; -- cgit v0.10.2 From 7f29673b2b20071a407af0a0a6acab8230912c6e Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Mon, 12 Mar 2007 11:39:01 +0100 Subject: [ALSA] hda-codec - Conexant improvements This patch further improves on the Conexant Audio driver. Adds support for Fujistu Siemens Si1520 series laptops. Adds support for mic/line in on CX20549 based systems (aka 5045). removes duplicated or unused controls (gpio, spdif) from test model. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 46e93c6..c7fb0b8 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -452,115 +452,6 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, .put = conexant_ch_mode_put, \ .private_value = nid | (dir<<16) } -static int cxt_gpio_data_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int cxt_gpio_data_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long *valp = ucontrol->value.integer.value; - unsigned int val = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_GPIO_DATA, 0x00); - - *valp = (val & mask) != 0; - return 0; -} - -static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long val = *ucontrol->value.integer.value; - unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_GPIO_DATA, - 0x00); - unsigned int old_data = gpio_data; - - /* Set/unset the masked GPIO bit(s) as needed */ - if (val == 0) - gpio_data &= ~mask; - else - gpio_data |= mask; - if (gpio_data == old_data && !codec->in_resume) - return 0; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data); - return 1; -} - -#define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \ - { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ - .info = cxt_gpio_data_info, \ - .get = cxt_gpio_data_get, \ - .put = cxt_gpio_data_put, \ - .private_value = nid | (mask<<16) } -#if 0 -static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - return 0; -} - -static int cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long *valp = ucontrol->value.integer.value; - unsigned int val = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_DIGI_CONVERT, 0x00); - - *valp = (val & mask) != 0; - return 0; -} - -static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long val = *ucontrol->value.integer.value; - unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_DIGI_CONVERT, - 0x00); - unsigned int old_data = ctrl_data; - - /* Set/unset the masked control bit(s) as needed */ - if (val == 0) - ctrl_data &= ~mask; - else - ctrl_data |= mask; - if (ctrl_data == old_data && !codec->in_resume) - return 0; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, - ctrl_data); - return 1; -} - -#define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \ - { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ - .info = cxt_spdif_ctrl_info, \ - .get = cxt_spdif_ctrl_get, \ - .put = cxt_spdif_ctrl_put, \ - .private_value = nid | (mask<<16) } -#endif #endif /* CONFIG_SND_DEBUG */ /* Conexant 5045 specific */ @@ -599,6 +490,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80; snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); + bits = spec->cur_eapd ? 0 : 0x80; snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits); snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits); @@ -624,6 +516,29 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol, return change; } +/* toggle input of built-in and mic jack appropriately */ +static void cxt5045_hp_automic(struct hda_codec *codec) +{ + static struct hda_verb mic_jack_on[] = { + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + {} + }; + static struct hda_verb mic_jack_off[] = { + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + {} + }; + unsigned int present; + + present = snd_hda_codec_read(codec, 0x12, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + if (present) + snd_hda_sequence_write(codec, mic_jack_on); + else + snd_hda_sequence_write(codec, mic_jack_off); +} + /* mute internal speaker if HP is plugged */ static void cxt5045_hp_automute(struct hda_codec *codec) @@ -634,7 +549,7 @@ static void cxt5045_hp_automute(struct hda_codec *codec) spec->hp_present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; + bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); } @@ -648,6 +563,10 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, case CONEXANT_HP_EVENT: cxt5045_hp_automute(codec); break; + case CONEXANT_MIC_EVENT: + cxt5045_hp_automic(codec); + break; + } } @@ -659,12 +578,10 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { .get = conexant_mux_enum_get, .put = conexant_mux_enum_put }, - HDA_CODEC_VOLUME("Int Mic Volume", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Switch", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Volume", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Switch", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Volume", @@ -688,7 +605,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { static struct hda_verb cxt5045_init_verbs[] = { /* Line in, Mic */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, /* HP, Amp */ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, {0x17, AC_VERB_SET_CONNECT_SEL,0x01}, @@ -701,18 +618,27 @@ static struct hda_verb cxt5045_init_verbs[] = { {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04}, /* Record selector: Int mic */ - {0x1a, AC_VERB_SET_CONNECT_SEL,0x0}, + {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, /* SPDIF route: PCM */ { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 }, - /* pin sensing on HP and Mic jacks */ - {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, /* EAPD */ {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ { } /* end */ }; + +static struct hda_verb cxt5045_hp_sense_init_verbs[] = { + /* pin sensing on HP jack */ + {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, +}; + +static struct hda_verb cxt5045_mic_sense_init_verbs[] = { + /* pin sensing on HP jack */ + {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, +}; + #ifdef CONFIG_SND_DEBUG /* Test configuration for debugging, modelled after the ALC260 test * configuration. @@ -733,6 +659,10 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { /* Output controls */ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT), /* Modes for retasking pin widgets */ CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), @@ -742,25 +672,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0), /* Loopback mixer controls */ - HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("LINE loopback Playback Volume", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("LINE loopback Playback Switch", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x17, 0x03, HDA_INPUT), - HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x17, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT), - - HDA_CODEC_VOLUME("Capture-1 Volume", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture-1 Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-2 Volume", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Capture-2 Switch", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-3 Volume", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Capture-3 Switch", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-4 Volume", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("Capture-4 Switch", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-5 Volume", 0x17, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("Capture-5 Switch", 0x17, 0x4, HDA_INPUT), + + HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", @@ -768,14 +690,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { .get = conexant_mux_enum_get, .put = conexant_mux_enum_put, }, - { } /* end */ }; static struct hda_verb cxt5045_test_init_verbs[] = { + /* Set connections */ + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, + { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, + { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* Enable retasking pins as output, initially without power amp */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Disable digital (SPDIF) pins initially, but users can enable * them via a mixer switch. In the case of SPDIF-out, this initverb @@ -804,6 +729,7 @@ static struct hda_verb cxt5045_test_init_verbs[] = { * pin) */ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Mute all inputs to mixer widget (even unconnected ones) */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */ @@ -827,7 +753,8 @@ static int cxt5045_init(struct hda_codec *codec) enum { - CXT5045_LAPTOP, /* Laptops w/ EAPD support */ + CXT5045_LAPTOP, /* Laptops w/ EAPD support */ + CXT5045_FUJITSU, /* Laptops w/ EAPD support */ #ifdef CONFIG_SND_DEBUG CXT5045_TEST, #endif @@ -836,6 +763,7 @@ enum { static const char *cxt5045_models[CXT5045_MODELS] = { [CXT5045_LAPTOP] = "laptop", + [CXT5045_FUJITSU] = "fujitsu", #ifdef CONFIG_SND_DEBUG [CXT5045_TEST] = "test", #endif @@ -844,7 +772,8 @@ static const char *cxt5045_models[CXT5045_MODELS] = { static struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP), - SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU), + SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP), {} }; @@ -877,16 +806,23 @@ static int patch_cxt5045(struct hda_codec *codec) codec->patch_ops = conexant_patch_ops; - codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, cxt5045_models, cxt5045_cfg_tbl); switch (board_config) { case CXT5045_LAPTOP: + codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; + spec->input_mux = &cxt5045_capture_source; + spec->num_init_verbs = 2; + spec->init_verbs[1] = cxt5045_hp_sense_init_verbs; + spec->mixers[0] = cxt5045_mixers; + codec->patch_ops.init = cxt5045_init; + break; + case CXT5045_FUJITSU: spec->input_mux = &cxt5045_capture_source; spec->num_init_verbs = 2; - spec->init_verbs[1] = cxt5045_init_verbs; + spec->init_verbs[1] = cxt5045_mic_sense_init_verbs; spec->mixers[0] = cxt5045_mixers; codec->patch_ops.init = cxt5045_init; break; @@ -913,10 +849,9 @@ static struct hda_channel_mode cxt5047_modes[1] = { }; static struct hda_input_mux cxt5047_capture_source = { - .num_items = 2, + .num_items = 1, .items = { - { "ExtMic", 0x0 }, - { "IntMic", 0x1 }, + { "Mic", 0x2 }, } }; @@ -1009,7 +944,7 @@ static void cxt5047_hp_automic(struct hda_codec *codec) }; unsigned int present; - present = snd_hda_codec_read(codec, 0x08, 0, + present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; if (present) snd_hda_sequence_write(codec, mic_jack_on); @@ -1033,15 +968,10 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec, } static struct snd_kcontrol_new cxt5047_mixers[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = conexant_mux_enum_info, - .get = conexant_mux_enum_get, - .put = conexant_mux_enum_put - }, HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Gain Volume", 0x1a, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Mic Gain Switch", 0x1a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), @@ -1133,18 +1063,18 @@ static struct hda_verb cxt5047_init_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, - /* HP, Amp, Speaker */ + /* HP, Speaker */ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - {0x1A, AC_VERB_SET_CONNECT_SEL,0x00}, - {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, - {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, {0x1d, AC_VERB_SET_CONNECT_SEL,0x0}, - /* Record selector: Front mic */ + /* Record selector: Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, + {0x1A, AC_VERB_SET_CONNECT_SEL,0x02}, + {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, + AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, + {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, + AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, /* SPDIF route: PCM */ { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* Enable unsolicited events */ @@ -1161,8 +1091,6 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = { {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, /* Speaker routing */ {0x1d, AC_VERB_SET_CONNECT_SEL,0x1}, - /* Change default to ExtMic for recording */ - {0x1a, AC_VERB_SET_CONNECT_SEL,0x2}, {} }; @@ -1172,7 +1100,6 @@ static struct hda_verb cxt5047_hp_init_verbs[] = { {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, /* Record selector: Ext Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, - {0x1a, AC_VERB_SET_CONNECT_SEL,0x02}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, /* Speaker routing */ @@ -1242,14 +1169,6 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = { .get = conexant_mux_enum_get, .put = conexant_mux_enum_put, }, - /* Controls for GPIO pins, assuming they exist and are configured - * as outputs - */ - CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), - CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), - CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), - CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), - { } /* end */ }; -- cgit v0.10.2 From e9024ccc2d54a71dfac583ede6082e265264d871 Mon Sep 17 00:00:00 2001 From: John Utz Date: Mon, 12 Mar 2007 12:30:06 +0100 Subject: [ALSA] ac97 - Smart 5.1 for VIA 1617a codec This patch provides a single 8 way enum called 'Smart 5.1 Select' with some reasonable names for each enum that allows the user to choose which of the 8 possible settings for vt1617a's version of what via calls 'Smart 5.1'. Signed-off-by: John Utz Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 43455fc..3eac0f8 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -3277,16 +3277,111 @@ static int patch_vt1616(struct snd_ac97 * ac97) /* * VT1617A codec */ -static int patch_vt1617a(struct snd_ac97 * ac97) + +/* + * unfortunately, the vt1617a stashes the twiddlers required for + * nooding the i/o jacks on 2 different regs. * thameans that we cant + * use the easy way provided by AC97_ENUM_DOUBLE() we have to write + * are own funcs. + * + * NB: this is absolutely and utterly different from the vt1618. dunno + * about the 1616. + */ + +/* copied from ac97_surround_jack_mode_info() */ +static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { - /* bring analog power consumption to normal, like WinXP driver - * for EPIA SP + /* ordering in this list reflects vt1617a docs for Reg 20 and + * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51 + * is SM51EN *AND* it's Bit14, not Bit15 so the table is very + * counter-intuitive */ + + static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3", + "Surr LFE/C Mic3", "LineIn LFE/C Mic3", + "LineIn Mic2", "LineIn Mic2 Mic1", + "Surr LFE Mic1", "Surr LFE Mic1 Mic2"}; + return ac97_enum_text_info(kcontrol, uinfo, texts, 8); +} + +static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ushort usSM51, usMS; + + struct snd_ac97 *pac97; + + pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ + + /* grab our desirec bits, then mash them together in a manner + * consistent with Table 6 on page 17 in the 1617a docs */ + + usSM51 = snd_ac97_read(pac97, 0x7a) >> 14; + usMS = snd_ac97_read(pac97, 0x20) >> 8; + + ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS; + + return 0; +} + +static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ushort usSM51, usMS, usReg; + + struct snd_ac97 *pac97; + + pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ + + usSM51 = ucontrol->value.enumerated.item[0] >> 1; + usMS = ucontrol->value.enumerated.item[0] & 1; + + /* push our values into the register - consider that things will be left + * in a funky state if the write fails */ + + usReg = snd_ac97_read(pac97, 0x7a); + snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14)); + usReg = snd_ac97_read(pac97, 0x20); + snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8)); + + return 0; +} + +static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = { + + AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0), + /* + * These are used to enable/disable surround sound on motherboards + * that have 3 bidirectional analog jacks + */ + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Smart 5.1 Select", + .info = snd_ac97_vt1617a_smart51_info, + .get = snd_ac97_vt1617a_smart51_get, + .put = snd_ac97_vt1617a_smart51_put, + }, +}; + +int patch_vt1617a(struct snd_ac97 * ac97) +{ + int err = 0; + + /* we choose to not fail out at this point, but we tell the + caller when we return */ + + err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0], + ARRAY_SIZE(snd_ac97_controls_vt1617a)); + + /* bring analog power consumption to normal by turning off the + * headphone amplifier, like WinXP driver for EPIA SP */ snd_ac97_write_cache(ac97, 0x5c, 0x20); ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; ac97->build_ops = &patch_vt1616_ops; - return 0; + + return err; } /* -- cgit v0.10.2 From 2549413ea6c17c94e42ab14611e487d96c787578 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 12 Mar 2007 12:36:16 +0100 Subject: [ALSA] hda-codec - Code clean up of patch_sigmatel.c - Remove superfluous array member in stac9205_dmic_nids[] - Use ARRAY_SIZE() instead of hard-coded numbers Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index fef56ef..7a82413 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -175,8 +175,8 @@ static hda_nid_t stac9205_mux_nids[2] = { 0x19, 0x1a }; -static hda_nid_t stac9205_dmic_nids[3] = { - 0x17, 0x18, 0 +static hda_nid_t stac9205_dmic_nids[2] = { + 0x17, 0x18, }; static hda_nid_t stac9200_pin_nids[8] = { @@ -1931,7 +1931,7 @@ static int patch_stac922x(struct hda_codec *codec) spec->adc_nids = stac922x_adc_nids; spec->mux_nids = stac922x_mux_nids; - spec->num_muxes = 2; + spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids); spec->num_dmics = 0; spec->init = stac922x_core_init; @@ -1992,7 +1992,7 @@ static int patch_stac927x(struct hda_codec *codec) case STAC_D965_3ST: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; - spec->num_muxes = 3; + spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); spec->num_dmics = 0; spec->init = d965_core_init; spec->mixer = stac9227_mixer; @@ -2000,7 +2000,7 @@ static int patch_stac927x(struct hda_codec *codec) case STAC_D965_5ST: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; - spec->num_muxes = 3; + spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); spec->num_dmics = 0; spec->init = d965_core_init; spec->mixer = stac9227_mixer; @@ -2008,7 +2008,7 @@ static int patch_stac927x(struct hda_codec *codec) default: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; - spec->num_muxes = 3; + spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); spec->num_dmics = 0; spec->init = stac927x_core_init; spec->mixer = stac927x_mixer; @@ -2067,9 +2067,9 @@ static int patch_stac9205(struct hda_codec *codec) spec->adc_nids = stac9205_adc_nids; spec->mux_nids = stac9205_mux_nids; - spec->num_muxes = 2; + spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); spec->dmic_nids = stac9205_dmic_nids; - spec->num_dmics = 2; + spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids); spec->dmux_nid = 0x1d; spec->init = stac9205_core_init; -- cgit v0.10.2 From 3396b33c8eab1b06f7cd2a63069fd7a04f02d8fb Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 12 Mar 2007 12:53:38 +0100 Subject: [ALSA] remove unused header file: sound/pci/cs46xx/imgs/cwcemb80.h Signed-off-by: Robert P. J. Day Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/cs46xx/imgs/cwcemb80.h b/sound/pci/cs46xx/imgs/cwcemb80.h deleted file mode 100644 index a64c6ff..0000000 --- a/sound/pci/cs46xx/imgs/cwcemb80.h +++ /dev/null @@ -1,1607 +0,0 @@ -/* generated from cwcemb80.osp DO NOT MODIFY */ - -#ifndef __HEADER_cwcemb80_H__ -#define __HEADER_cwcemb80_H__ - -static struct dsp_symbol_entry cwcemb80_symbols[] = { - { 0x0000, "BEGINADDRESS",0x00 }, - { 0x8000, "EXECCHILD",0x03 }, - { 0x8001, "EXECCHILD_98",0x03 }, - { 0x8003, "EXECCHILD_PUSH1IND",0x03 }, - { 0x8008, "EXECSIBLING",0x03 }, - { 0x800a, "EXECSIBLING_298",0x03 }, - { 0x800b, "EXECSIBLING_2IND1",0x03 }, - { 0x8010, "TIMINGMASTER",0x03 }, - { 0x804f, "S16_CODECINPUTTASK",0x03 }, - { 0x805e, "PCMSERIALINPUTTASK",0x03 }, - { 0x806d, "S16_MIX_TO_OSTREAM",0x03 }, - { 0x809a, "S16_MIX",0x03 }, - { 0x80bb, "S16_UPSRC",0x03 }, - { 0x813b, "MIX3_EXP",0x03 }, - { 0x8164, "DECIMATEBYPOW2",0x03 }, - { 0x8197, "VARIDECIMATE",0x03 }, - { 0x81f2, "_3DINPUTTASK",0x03 }, - { 0x820a, "_3DPRLGCINPTASK",0x03 }, - { 0x8227, "_3DSTEREOINPUTTASK",0x03 }, - { 0x8242, "_3DOUTPUTTASK",0x03 }, - { 0x82c4, "HRTF_MORPH_TASK",0x03 }, - { 0x82c6, "WAIT4DATA",0x03 }, - { 0x82fa, "PROLOGIC",0x03 }, - { 0x8496, "DECORRELATOR",0x03 }, - { 0x84a4, "STEREO2MONO",0x03 }, - { 0x0070, "SPOSCB",0x02 }, - { 0x0105, "TASKTREETHREAD",0x03 }, - { 0x0136, "TASKTREEHEADERCODE",0x03 }, - { 0x013f, "FGTASKTREEHEADERCODE",0x03 }, - { 0x0163, "NULLALGORITHM",0x03 }, - { 0x0167, "HFGEXECCHILD",0x03 }, - { 0x0168, "HFGEXECCHILD_98",0x03 }, - { 0x016a, "HFGEXECCHILD_PUSH1IND",0x03 }, - { 0x016d, "HFGEXECSIBLING",0x03 }, - { 0x016f, "HFGEXECSIBLING_298",0x03 }, - { 0x0170, "HFGEXECSIBLING_2IND1",0x03 }, - { 0x0173, "S16_CODECOUTPUTTASK",0x03 }, - { 0x018e, "#CODE_END",0x00 }, -}; /* cwcemb80 symbols */ - -static u32 cwcemb80_code[] = { -/* BEGINADDRESS */ -/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003, -/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003, -/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003, -/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003, -/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003, -/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003, -/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003, -/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003, -/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003, -/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040, -/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003, -/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003, -/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003, -/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003, -/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003, -/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003, -/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003, -/* 0040 */ 0x0000a730,0x00001008,0x000e2730,0x00001002, -/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003, -/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000, -/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000, -/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000, -/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000, -/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000, -/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003, -/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003, -/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000, -/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003, -/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000, -/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000, -/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000, -/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140, -/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, -/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, -/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40, -/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00, -/* 007C */ 0x0000002e,0x0009d6c0,0x00038630,0x00001004, -/* 007E */ 0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000, -/* 0080 */ 0x00000000,0x000c70e0,0x0007d182,0x0002c640, -/* 0082 */ 0x00000630,0x00001004,0x000799b8,0x0002c6c0, -/* 0084 */ 0x00031705,0x00092240,0x00039f05,0x000932c0, -/* 0086 */ 0x0003520a,0x00000000,0x00040731,0x0000100b, -/* 0088 */ 0x00010705,0x000b20c0,0x00000000,0x000eba44, -/* 008A */ 0x00032108,0x000c60c4,0x00065208,0x000c2917, -/* 008C */ 0x000406b0,0x00001007,0x00012f05,0x00036880, -/* 008E */ 0x0002818e,0x000c0000,0x0004410a,0x00000000, -/* 0090 */ 0x00040630,0x00001007,0x00029705,0x000c0000, -/* 0092 */ 0x00000000,0x00000000,0x00003fc1,0x0003fc40, -/* 0094 */ 0x000037c1,0x00091b40,0x00003fc1,0x000911c0, -/* 0096 */ 0x000037c1,0x000957c0,0x00003fc1,0x000951c0, -/* 0098 */ 0x000037c1,0x00000000,0x00003fc1,0x000991c0, -/* 009A */ 0x000037c1,0x00000000,0x00003fc1,0x0009d1c0, -/* 009C */ 0x000037c1,0x00000000,0x0001ccc1,0x000915c0, -/* 009E */ 0x0001c441,0x0009d800,0x0009cdc1,0x00091240, -/* 00A0 */ 0x0001c541,0x00091d00,0x0009cfc1,0x00095240, -/* 00A2 */ 0x0001c741,0x00095c80,0x000e8ca9,0x00099240, -/* 00A4 */ 0x000e85ad,0x00095640,0x00069ca9,0x00099d80, -/* 00A6 */ 0x000e952d,0x00099640,0x000eaca9,0x0009d6c0, -/* 00A8 */ 0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80, -/* 00AA */ 0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0, -/* 00AC */ 0x000ec5ad,0x0009da40,0x000edca9,0x0009d300, -/* 00AE */ 0x000a6e0a,0x00001000,0x000ed52d,0x00091e40, -/* 00B0 */ 0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40, -/* 00B2 */ 0x0006fca9,0x00002500,0x000fb208,0x000c59a0, -/* 00B4 */ 0x000ef52d,0x0009de40,0x00068ca9,0x000912c1, -/* 00B6 */ 0x000683ad,0x00095241,0x00020f05,0x000991c1, -/* 00B8 */ 0x00000000,0x00000000,0x00086f88,0x00001000, -/* 00BA */ 0x0009cf81,0x000b5340,0x0009c701,0x000b92c0, -/* 00BC */ 0x0009de81,0x000bd300,0x0009d601,0x000b1700, -/* 00BE */ 0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0, -/* 00C0 */ 0x000a0f81,0x000bd740,0x00020701,0x000b5c80, -/* 00C2 */ 0x000a1681,0x000b97c0,0x00021601,0x00002500, -/* 00C4 */ 0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0, -/* 00C6 */ 0x00021681,0x00002d00,0x00020f81,0x000bd800, -/* 00C8 */ 0x000a0701,0x000b5bc0,0x00021601,0x00003500, -/* 00CA */ 0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0, -/* 00CC */ 0x00021681,0x00003d00,0x00020f81,0x000b1d00, -/* 00CE */ 0x000a0701,0x000b1fc0,0x00021601,0x00020500, -/* 00D0 */ 0x00020f81,0x000b1341,0x000a0701,0x000b9fc0, -/* 00D2 */ 0x00021681,0x00020d00,0x00020f81,0x000bde80, -/* 00D4 */ 0x000a0701,0x000bdfc0,0x00021601,0x00021500, -/* 00D6 */ 0x00020f81,0x000b9341,0x00020701,0x000b53c1, -/* 00D8 */ 0x00021681,0x00021d00,0x000a0f81,0x000d0380, -/* 00DA */ 0x0000b601,0x000b15c0,0x00007b01,0x00000000, -/* 00DC */ 0x00007b81,0x000bd1c0,0x00007b01,0x00000000, -/* 00DE */ 0x00007b81,0x000b91c0,0x00007b01,0x000b57c0, -/* 00E0 */ 0x00007b81,0x000b51c0,0x00007b01,0x000b1b40, -/* 00E2 */ 0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0, -/* 00E4 */ 0x0007e488,0x000d7e45,0x00000000,0x000d7a44, -/* 00E6 */ 0x0007e48a,0x00000000,0x00011f05,0x00084080, -/* 00E8 */ 0x00000000,0x00000000,0x00001705,0x000b3540, -/* 00EA */ 0x00008a01,0x000bf040,0x00007081,0x000bb5c0, -/* 00EC */ 0x00055488,0x00000000,0x0000d482,0x0003fc40, -/* 00EE */ 0x0003fc88,0x00000000,0x0001e401,0x000b3a00, -/* 00F0 */ 0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784, -/* 00F2 */ 0x000c86b0,0x00001007,0x00008281,0x000bb240, -/* 00F4 */ 0x0000b801,0x000b7140,0x00007888,0x00000000, -/* 00F6 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000, -/* 00F8 */ 0x00000000,0x00000000,0x00055288,0x000c555c, -/* 00FA */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00, -/* 00FC */ 0x0000fa88,0x00000000,0x00000032,0x00001000, -/* 00FE */ 0x0000073d,0x00001000,0x0007f188,0x000c0000, -/* 0100 */ 0x00000000,0x00000000,0x0008c01c,0x00001003, -/* 0102 */ 0x00002705,0x00001008,0x0008b201,0x000c1392, -/* 0104 */ 0x0000ba01,0x00000000, -/* TASKTREETHREAD */ -/* 0105 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4, -/* 0107 */ 0x00057488,0x00000000,0x000a6388,0x00001001, -/* 0109 */ 0x0008b334,0x000bc141,0x0003020e,0x00000000, -/* 010B */ 0x000886b0,0x00001008,0x00003625,0x000c5dfa, -/* 010D */ 0x000a638a,0x00001001,0x0008020e,0x00001002, -/* 010F */ 0x0008a6b0,0x00001008,0x0007f301,0x00000000, -/* 0111 */ 0x00000000,0x00000000,0x00002725,0x000a8c40, -/* 0113 */ 0x000000ae,0x00000000,0x000d8630,0x00001008, -/* 0115 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640, -/* 0117 */ 0x000a8630,0x00001008,0x000799b8,0x0002d6c0, -/* 0119 */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000, -/* 011B */ 0x00062208,0x000c4117,0x00070630,0x00001009, -/* 011D */ 0x00000000,0x000c0000,0x0001022e,0x00000000, -/* 011F */ 0x0003a630,0x00001009,0x00000000,0x000c0000, -/* 0121 */ 0x00000036,0x00001000,0x00000000,0x00000000, -/* 0123 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0125 */ 0x00000000,0x00000000,0x0002a730,0x00001008, -/* 0127 */ 0x0007f801,0x000c0000,0x00000037,0x00001000, -/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012B */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012D */ 0x0002a730,0x00001008,0x00000033,0x00001000, -/* 012F */ 0x0002a705,0x00001008,0x00007a01,0x000c0000, -/* 0131 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000, -/* 0133 */ 0x00060730,0x0000100a,0x00000000,0x000c0000, -/* 0135 */ 0x00000000,0x00000000, -/* TASKTREEHEADERCODE */ -/* 0136 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100b, -/* 0138 */ 0x00057488,0x00000000,0x00033b94,0x00081140, -/* 013A */ 0x000183ae,0x00000000,0x000786b0,0x0000100b, -/* 013C */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000, -/* 013E */ 0x00042731,0x00001003, -/* FGTASKTREEHEADERCODE */ -/* 013F */ 0x0007aab0,0x00034880,0x00048fb0,0x0000100a, -/* 0141 */ 0x00057488,0x00000000,0x00033b94,0x00081140, -/* 0143 */ 0x000183ae,0x00000000,0x000806b0,0x0000100b, -/* 0145 */ 0x00022f05,0x00000000,0x00007401,0x00091140, -/* 0147 */ 0x00048f05,0x000951c0,0x00042731,0x00001003, -/* 0149 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47, -/* 014B */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003, -/* 014D */ 0x00000000,0x00000000,0x0008e19c,0x00001003, -/* 014F */ 0x000083c1,0x00093040,0x00000f41,0x00097140, -/* 0151 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, -/* 0153 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, -/* 0155 */ 0x00000000,0x000fdc44,0x00055208,0x00000000, -/* 0157 */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00, -/* 0159 */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000, -/* 015B */ 0x00012f05,0x00036880,0x00065308,0x000c2997, -/* 015D */ 0x000d86b0,0x0000100a,0x0004410a,0x000d40c7, -/* 015F */ 0x00000000,0x00000000,0x00080730,0x00001004, -/* 0161 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000, -/* NULLALGORITHM */ -/* 0163 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47, -/* 0165 */ 0x00080000,0x000bffc7,0x0000273d,0x00001000, -/* HFGEXECCHILD */ -/* 0167 */ 0x00000000,0x000eba44, -/* HFGEXECCHILD_98 */ -/* 0168 */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0, -/* HFGEXECCHILD_PUSH1IND */ -/* 016A */ 0x00000734,0x00001000,0x00010705,0x000a6880, -/* 016C */ 0x00006a88,0x000c75c4, -/* HFGEXECSIBLING */ -/* 016D */ 0x00000000,0x000e5084,0x00000000,0x000eba44, -/* HFGEXECSIBLING_298 */ -/* 016F */ 0x00087401,0x000e4782, -/* HFGEXECSIBLING_2IND1 */ -/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880, -/* 0172 */ 0x00006a88,0x000c75c4, -/* S16_CODECOUTPUTTASK */ -/* 0173 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40, -/* 0175 */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80, -/* 0177 */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0, -/* 0179 */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0, -/* 017B */ 0x00073fb0,0x00074c80,0x000283a0,0x0000100c, -/* 017D */ 0x000ee388,0x00042970,0x00008301,0x00021ef2, -/* 017F */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b, -/* 0181 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916, -/* 0183 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000, -/* 0185 */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b, -/* 0187 */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956, -/* 0189 */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40, -/* 018B */ 0x00058730,0x00001400,0x000d7488,0x000c3a00, -/* 018D */ 0x00048f05,0x00000000 -}; -/* #CODE_END */ - -static u32 cwcemb80_parameter[] = { -/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0008 */ 0x00000000,0x00000000,0x00000163,0x00000000, -/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0018 */ 0x00000000,0x00200040,0x00008010,0x00000000, -/* 001C */ 0x00000000,0x80000001,0x00000001,0x00060000, -/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0028 */ 0x00000000,0x00900080,0x00000173,0x00000000, -/* 002C */ 0x00000000,0x00000010,0x00800000,0x00900000, -/* 0030 */ 0xf2c0000f,0x00000200,0x00000000,0x00010600, -/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0038 */ 0x00000000,0x00000000,0x00000163,0x330300c2, -/* 003C */ 0x06000000,0x00000000,0x80008000,0x80008000, -/* 0040 */ 0x3fc0000f,0x00000301,0x00010400,0x00000000, -/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0048 */ 0x00000000,0x00b00000,0x00d0806d,0x330480c3, -/* 004C */ 0x04800000,0x00000001,0x00800001,0x0000ffff, -/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0070 */ 0x066a0600,0x06350070,0x0000929d,0x929d929d, -/* 0074 */ 0x00000000,0x0000735a,0x00000600,0x00000000, -/* 0078 */ 0x929d735a,0x00000000,0x00010000,0x735a735a, -/* 007C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0088 */ 0x00000000,0x00000000,0x0000804f,0x000000c3, -/* 008C */ 0x05000000,0x00a00010,0x00000000,0x80008000, -/* 0090 */ 0x00000000,0x00000000,0x00000700,0x00000000, -/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0098 */ 0x00000080,0x00a00000,0x0000809a,0x000000c2, -/* 009C */ 0x07400000,0x00000000,0x80008000,0xffffffff, -/* 00A0 */ 0x00c80028,0x00005555,0x00000000,0x000107a0, -/* 00A4 */ 0x00c80028,0x000000c2,0x06800000,0x00000000, -/* 00A8 */ 0x06e00080,0x00300000,0x000080bb,0x000000c9, -/* 00AC */ 0x07a00000,0x04000000,0x80008000,0xffffffff, -/* 00B0 */ 0x00c80028,0x00005555,0x00000000,0x00000780, -/* 00B4 */ 0x00c80028,0x000000c5,0xff800000,0x00000000, -/* 00B8 */ 0x00640080,0x00c00000,0x00008197,0x000000c9, -/* 00BC */ 0x07800000,0x04000000,0x80008000,0xffffffff, -/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C8 */ 0x00000000,0x00000000,0x0000805e,0x000000c1, -/* 00CC */ 0x00000000,0x00800000,0x80008000,0x80008000, -/* 00D0 */ 0x00020000,0x0000ffff,0x00000000,0x00000000, -/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0600 */ 0x929d0600,0x929d929d,0x929d929d,0x929d0000, -/* 0604 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d, -/* 0608 */ 0x929d929d,0x00100635,0x060b013f,0x00000004, -/* 060C */ 0x00000001,0x007a0002,0x00000000,0x066e0610, -/* 0610 */ 0x0105929d,0x929d929d,0x929d929d,0x929d929d, -/* 0614 */ 0x929d929d,0xa431ac75,0x0001735a,0xa431ac75, -/* 0618 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 061C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0620 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0624 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0628 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 062C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0630 */ 0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051, -/* 0634 */ 0x00000000,0x929d929d,0x929d929d,0x929d929d, -/* 0638 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d, -/* 063C */ 0x929d929d,0x929d929d,0x00000000,0x06400136, -/* 0640 */ 0x0000270f,0x00010000,0x007a0000,0x00000000, -/* 0644 */ 0x068e0645,0x0105929d,0x929d929d,0x929d929d, -/* 0648 */ 0x929d929d,0x929d929d,0xa431ac75,0x0001735a, -/* 064C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0650 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0654 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0658 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 065C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0660 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0664 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0668 */ 0x735a0100,0x00000000,0x00000000,0x00000000, -/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0694 */ 0x00000000,0x00000000,0x00000000 -}; /* #PARAMETER_END */ - -static u32 cwcemb80_sample[] = { -/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0088 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 008C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0090 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0098 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 009C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0600 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0604 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0608 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 060C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0610 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0614 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0618 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 061C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0620 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0624 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0628 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 062C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0630 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0634 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0638 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 063C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0640 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0644 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0648 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 064C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0650 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0654 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0658 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 065C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0660 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0664 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0668 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0694 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0698 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 069C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0700 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0704 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0708 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 070C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0710 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0714 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0718 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 071C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0720 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0724 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0728 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 072C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0730 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0734 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0738 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 073C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0740 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0744 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0748 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 074C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0750 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0754 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0758 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 075C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0760 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0764 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0768 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 076C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0770 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0774 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0778 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 077C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0780 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0784 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0788 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 078C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0790 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0794 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0798 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 079C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0800 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0804 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0808 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 080C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0810 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0814 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0818 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 081C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0820 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0824 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0828 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 082C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0830 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0834 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0838 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 083C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0840 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0844 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0848 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 084C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0850 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0854 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0858 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 085C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0860 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0864 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0868 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 086C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0870 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0874 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0878 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 087C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0880 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0884 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0888 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 088C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0890 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0894 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0898 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 089C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0900 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0904 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0908 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 090C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0910 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0914 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0918 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 091C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0920 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0924 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0928 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 092C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0930 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0934 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0938 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 093C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0940 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0944 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0948 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 094C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0950 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0954 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0958 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 095C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0960 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0964 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0968 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 096C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0970 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0974 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0978 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 097C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0980 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0984 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0988 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 098C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0990 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0994 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0998 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 099C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0ABC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0ACC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0ADC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AFC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BBC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BCC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BDC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BFC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CBC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CCC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CDC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CFC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DBC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DCC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DDC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DFC */ 0x00000000,0x00000000,0x00000000,0x00010004 -}; /* #SAMPLE_END */ - - -static struct dsp_segment_desc cwcemb80_segments[] = { - { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000031c, cwcemb80_code }, - { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000697, cwcemb80_parameter }, - { SEGTYPE_SP_SAMPLE, 0x00000000, 0x00000e00, cwcemb80_sample }, -}; - -static struct dsp_module_desc cwcemb80_module = { - "cwcemb80", - { - 38, - cwcemb80_symbols - }, - 3, - cwcemb80_segments, -}; - -#endif /* __HEADER_cwcemb80_H__ */ -- cgit v0.10.2 From 345a1e150ed722bded478e23d3d75b6b73c63d5c Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 12 Mar 2007 12:54:23 +0100 Subject: [ALSA] Delete unused header file sound/pci/au88x0/au88x0_sb.h Signed-off-by: Robert P. J. Day Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/au88x0/au88x0_sb.h b/sound/pci/au88x0/au88x0_sb.h deleted file mode 100644 index 5a4d8fc..0000000 --- a/sound/pci/au88x0/au88x0_sb.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * au88x0_sb.h - * - * Wed Oct 29 22:10:42 2003 - * - ****************************************************************************/ - -#ifdef CHIP_AU8820 -/* AU8820 starting @ 64KiB offset */ -#define SBEMU_BASE 0x10000 -#else -/* AU8810? and AU8830 starting @ 164KiB offset */ -#define SBEMU_BASE 0x29000 -#endif - -#define FM_A_STATUS (SBEMU_BASE + 0x00) /* read */ -#define FM_A_ADDRESS (SBEMU_BASE + 0x00) /* write */ -#define FM_A_DATA (SBEMU_BASE + 0x04) -#define FM_B_STATUS (SBEMU_BASE + 0x08) -#define FM_B_ADDRESS (SBEMU_BASE + 0x08) -#define FM_B_DATA (SBEMU_BASE + 0x0C) -#define SB_MIXER_ADDR (SBEMU_BASE + 0x10) -#define SB_MIXER_DATA (SBEMU_BASE + 0x14) -#define SB_RESET (SBEMU_BASE + 0x18) -#define SB_RESET_ALIAS (SBEMU_BASE + 0x1C) -#define FM_STATUS2 (SBEMU_BASE + 0x20) -#define FM_ADDR2 (SBEMU_BASE + 0x20) -#define FM_DATA2 (SBEMU_BASE + 0x24) -#define SB_DSP_READ (SBEMU_BASE + 0x28) -#define SB_DSP_WRITE (SBEMU_BASE + 0x30) -#define SB_DSP_WRITE_STATUS (SBEMU_BASE + 0x30) /* bit 7 */ -#define SB_DSP_READ_STATUS (SBEMU_BASE + 0x38) /* bit 7 */ -#define SB_LACR (SBEMU_BASE + 0x40) /* ? */ -#define SB_LADCR (SBEMU_BASE + 0x44) /* ? */ -#define SB_LAMR (SBEMU_BASE + 0x48) /* ? */ -#define SB_LARR (SBEMU_BASE + 0x4C) /* ? */ -#define SB_VERSION (SBEMU_BASE + 0x50) -#define SB_CTRLSTAT (SBEMU_BASE + 0x54) -#define SB_TIMERSTAT (SBEMU_BASE + 0x58) -#define FM_RAM (SBEMU_BASE + 0x100) /* 0x40 ULONG */ -- cgit v0.10.2 From 623ec04798bc21a611a5409f39bd3069cc64a80f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 13 Mar 2007 15:29:47 +0100 Subject: [ALSA] hda_intel: build fix CC [M] sound/pci/hda/hda_intel.o sound/pci/hda/hda_intel.c:1508: error: position_fix_list causes a section type conflict Gcc like its __devinitdata readable not const, it seems. An alternative fix would be to remove the __devinitdata attribute but that would result in slight runtime bloat. Signed-off-by: Ralf Baechle Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1672cac..517a8d7 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1518,7 +1518,7 @@ static int azx_dev_free(struct snd_device *device) /* * white/black-listing for position_fix */ -static const struct snd_pci_quirk position_fix_list[] __devinitdata = { +static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), {} }; -- cgit v0.10.2 From bf748ed73e6978657102bddb1c4cc8a8f342c484 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 13 Mar 2007 15:31:08 +0100 Subject: [ALSA] ice1712: build fixes CC [M] sound/pci/ice1712/ice1712.o sound/pci/ice1712/ice1712.c:290: error: snd_ice1712_mixer_digmix_route_ac97 causes a section type conflict sound/pci/ice1712/ice1712.c:1630: error: snd_ice1712_eeprom causes a section type conflict ... Gcc like its __devinitdata readable not const, it seems. An alternative fix would be to remove the __devinitdata attribute but that would result in slight runtime bloat. Signed-off-by: Ralf Baechle Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 3eeb36c..af65980 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -416,7 +416,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco return 0; } -static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = { .access = (SNDRV_CTL_ELEM_ACCESS_READ), .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -429,7 +429,7 @@ static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __ * initialize the chips on M-Audio cards */ -static const struct snd_akm4xxx akm_audiophile __devinitdata = { +static struct snd_akm4xxx akm_audiophile __devinitdata = { .type = SND_AK4528, .num_adcs = 2, .num_dacs = 2, @@ -438,7 +438,7 @@ static const struct snd_akm4xxx akm_audiophile __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { +static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = ICE1712_DELTA_AP_DOUT, @@ -450,7 +450,7 @@ static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_delta410 __devinitdata = { +static struct snd_akm4xxx akm_delta410 __devinitdata = { .type = SND_AK4529, .num_adcs = 2, .num_dacs = 8, @@ -459,7 +459,7 @@ static const struct snd_akm4xxx akm_delta410 __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { +static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { .caddr = 0, .cif = 0, .data_mask = ICE1712_DELTA_AP_DOUT, @@ -471,7 +471,7 @@ static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_delta1010lt __devinitdata = { +static struct snd_akm4xxx akm_delta1010lt __devinitdata = { .type = SND_AK4524, .num_adcs = 8, .num_dacs = 8, @@ -481,7 +481,7 @@ static const struct snd_akm4xxx akm_delta1010lt __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { +static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { .caddr = 2, .cif = 0, /* the default level of the CIF pin from AK4524 */ .data_mask = ICE1712_DELTA_1010LT_DOUT, @@ -493,7 +493,7 @@ static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_delta44 __devinitdata = { +static struct snd_akm4xxx akm_delta44 __devinitdata = { .type = SND_AK4524, .num_adcs = 4, .num_dacs = 4, @@ -503,7 +503,7 @@ static const struct snd_akm4xxx akm_delta44 __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { +static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { .caddr = 2, .cif = 0, /* the default level of the CIF pin from AK4524 */ .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA, @@ -515,7 +515,7 @@ static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_vx442 __devinitdata = { +static struct snd_akm4xxx akm_vx442 __devinitdata = { .type = SND_AK4524, .num_adcs = 4, .num_dacs = 4, @@ -525,7 +525,7 @@ static const struct snd_akm4xxx akm_vx442 __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_vx442_priv __devinitdata = { +static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = ICE1712_VX442_DOUT, @@ -650,15 +650,15 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) * additional controls for M-Audio cards */ -static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); -static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); -static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); -static const struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = +static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); -static const struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); @@ -735,7 +735,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice) /* entry point */ -const struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { { .subvendor = ICE1712_SUBDEVICE_DELTA1010, .name = "M Audio Delta 1010", diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h index e47861c..2697156 100644 --- a/sound/pci/ice1712/delta.h +++ b/sound/pci/ice1712/delta.h @@ -46,7 +46,7 @@ #define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 /* entry point */ -extern const struct snd_ice1712_card_info snd_ice1712_delta_cards[]; +extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; /* diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index 9b7ff30..b135389 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -332,7 +332,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate) /* */ -static const struct snd_akm4xxx akm_ews88mt __devinitdata = { +static struct snd_akm4xxx akm_ews88mt __devinitdata = { .num_adcs = 8, .num_dacs = 8, .type = SND_AK4524, @@ -342,7 +342,7 @@ static const struct snd_akm4xxx akm_ews88mt __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_EWS88_SERIAL_DATA, @@ -354,7 +354,7 @@ static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_ewx2496 __devinitdata = { +static struct snd_akm4xxx akm_ewx2496 __devinitdata = { .num_adcs = 2, .num_dacs = 2, .type = SND_AK4524, @@ -363,7 +363,7 @@ static const struct snd_akm4xxx akm_ewx2496 __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_EWS88_SERIAL_DATA, @@ -375,7 +375,7 @@ static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_6fire __devinitdata = { +static struct snd_akm4xxx akm_6fire __devinitdata = { .num_adcs = 6, .num_dacs = 6, .type = SND_AK4524, @@ -384,7 +384,7 @@ static const struct snd_akm4xxx akm_6fire __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_6fire_priv __devinitdata = { +static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_6FIRE_SERIAL_DATA, @@ -578,7 +578,7 @@ static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct sn return val != nval; } -static const struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Sensitivity Switch", @@ -678,7 +678,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st return ndata != data; } -static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Sensitivity Switch", .info = snd_ice1712_ewx_io_sense_info, @@ -687,7 +687,7 @@ static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitda .count = 8, }; -static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Output Sensitivity Switch", .info = snd_ice1712_ewx_io_sense_info, @@ -769,7 +769,7 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct .private_value = xshift | (xinvert << 8),\ } -static const struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */ EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), @@ -909,7 +909,7 @@ static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, str .private_value = xshift | (xinvert << 8),\ } -static const struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Analog Input Select", @@ -989,7 +989,7 @@ static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice) /* entry point */ -const struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { { .subvendor = ICE1712_SUBDEVICE_EWX2496, .name = "TerraTec EWX24/96", diff --git a/sound/pci/ice1712/ews.h b/sound/pci/ice1712/ews.h index df449b4..a12a0b0 100644 --- a/sound/pci/ice1712/ews.h +++ b/sound/pci/ice1712/ews.h @@ -40,7 +40,7 @@ #define ICE1712_SUBDEVICE_PHASE88 0x3b155111 /* entry point */ -extern const struct snd_ice1712_card_info snd_ice1712_ews_cards[]; +extern struct snd_ice1712_card_info snd_ice1712_ews_cards[]; /* TerraTec EWX 24/96 configuration definitions */ diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index df97313..8203562 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c @@ -239,7 +239,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip) static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) { /* Hoontech STDSP24 with modified hardware */ - static const struct snd_akm4xxx akm_stdsp24_mv __devinitdata = { + static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = { .num_adcs = 2, .num_dacs = 2, .type = SND_AK4524, @@ -248,7 +248,7 @@ static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) } }; - static const struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = { + static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_STDSP24_SERIAL_DATA, @@ -298,7 +298,7 @@ static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice) /* entry point */ -const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = { { .subvendor = ICE1712_SUBDEVICE_STDSP24, .name = "Hoontech SoundTrack Audio DSP24", diff --git a/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h index b62d6e4..1ee538b 100644 --- a/sound/pci/ice1712/hoontech.h +++ b/sound/pci/ice1712/hoontech.h @@ -35,7 +35,7 @@ #define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */ #define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */ -extern const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; +extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; /* Hoontech SoundTrack Audio DSP 24 GPIO definitions */ diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index e880469..6630a0a 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -287,7 +287,7 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru return val != nval; } -static const struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Digital Mixer To AC97", .info = snd_ice1712_digmix_route_ac97_info, @@ -1378,7 +1378,7 @@ static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struc static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); -static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Playback Switch", @@ -1402,7 +1402,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devini }, }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "H/W Multi Capture Switch", .info = snd_ice1712_pro_mixer_switch_info, @@ -1411,7 +1411,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __d .private_value = 10, }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH), .info = snd_ice1712_pro_mixer_switch_info, @@ -1421,7 +1421,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __de .count = 2, }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), @@ -1433,7 +1433,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __d .tlv = { .p = db_scale_playback } }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME), .info = snd_ice1712_pro_mixer_volume_info, @@ -1625,7 +1625,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = "ICE1712 EEPROM", .access = SNDRV_CTL_ELEM_ACCESS_READ, @@ -1661,7 +1661,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -1712,7 +1712,7 @@ static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1721,7 +1721,7 @@ static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = .get = snd_ice1712_spdif_maskc_get, }; -static const struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1748,7 +1748,7 @@ static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), @@ -1889,7 +1889,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Internal Clock", .info = snd_ice1712_pro_internal_clock_info, @@ -1960,7 +1960,7 @@ static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcont return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Internal Clock Default", .info = snd_ice1712_pro_internal_clock_default_info, @@ -1999,7 +1999,7 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Locking", .info = snd_ice1712_pro_rate_locking_info, @@ -2038,7 +2038,7 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Reset", .info = snd_ice1712_pro_rate_reset_info, @@ -2205,7 +2205,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "H/W Playback Route", .info = snd_ice1712_pro_route_info, @@ -2213,7 +2213,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devini .put = snd_ice1712_pro_route_analog_put, }; -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = snd_ice1712_pro_route_info, @@ -2255,7 +2255,7 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Volume Rate", .info = snd_ice1712_pro_volume_rate_info, @@ -2288,7 +2288,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Peak", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, @@ -2303,7 +2303,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = /* * list of available boards */ -static const struct snd_ice1712_card_info *card_tables[] __devinitdata = { +static struct snd_ice1712_card_info *card_tables[] __devinitdata = { snd_ice1712_hoontech_cards, snd_ice1712_delta_cards, snd_ice1712_ews_cards, @@ -2327,7 +2327,7 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice, { int dev = 0xa0; /* EEPROM device address */ unsigned int i, size; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (! modelname || ! *modelname) { ice->eeprom.subvendor = 0; @@ -2656,7 +2656,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card, * */ -static const struct snd_ice1712_card_info no_matched __devinitdata; +static struct snd_ice1712_card_info no_matched __devinitdata; static int __devinit snd_ice1712_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) @@ -2665,7 +2665,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, struct snd_card *card; struct snd_ice1712 *ice; int pcm_dev = 0, err; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (dev >= SNDRV_CARDS) return -ENODEV; -- cgit v0.10.2 From 1b60f6b0904737cb76cd4cd46b57592318c9a20e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Mar 2007 22:13:47 +0100 Subject: [ALSA] Fix conflicts between const and __devinitdata Marvin told with a depressed face, gcc doesn't like both __devinitdata and const in the same line. So, remove const from all over places now... Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 43edd28..e7daddd 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -622,7 +622,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol, return (nreg != oreg); } -static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = { AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1), AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1), AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1), @@ -678,7 +678,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata #endif }; -static const u16 __devinitdata snd_azf3328_init_values[][2] = { +static u16 __devinitdata snd_azf3328_init_values[][2] = { { IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f }, { IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f }, { IDX_MIXER_BASSTREBLE, 0x0000 }, diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c index 6e22d32..44bbb63 100644 --- a/sound/pci/ice1712/amp.c +++ b/sound/pci/ice1712/amp.c @@ -75,7 +75,7 @@ static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice) /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_AV710, .name = "Chaintech AV-710", diff --git a/sound/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h index 7b667ba..a0fc89b 100644 --- a/sound/pci/ice1712/amp.h +++ b/sound/pci/ice1712/amp.h @@ -42,7 +42,7 @@ #define WM_DAC_CTRL 0x02 #define WM_INT_CTRL 0x03 -extern const struct snd_ice1712_card_info snd_vt1724_amp_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_amp_cards[]; #endif /* __SOUND_AMP_H */ diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 6941d85..66bacde 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -1411,7 +1411,7 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl * mixers */ -static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { +static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -1526,7 +1526,7 @@ static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new wm_controls[] __devinitdata = { +static struct snd_kcontrol_new wm_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "PCM Playback Switch", @@ -1592,7 +1592,7 @@ static const struct snd_kcontrol_new wm_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new ac97_controls[] __devinitdata = { +static struct snd_kcontrol_new ac97_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "AC97 Playback Switch", @@ -1697,7 +1697,7 @@ static const struct snd_kcontrol_new ac97_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { +static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "AC97 Playback Switch", @@ -1829,7 +1829,7 @@ static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { }; -static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = { +static struct snd_kcontrol_new cs8415_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), @@ -2107,7 +2107,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char aureon51_eeprom[] __devinitdata = { +static unsigned char aureon51_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -2123,7 +2123,7 @@ static const unsigned char aureon51_eeprom[] __devinitdata = { [ICE_EEP2_GPIO_STATE2] = 0x00, }; -static const unsigned char aureon71_eeprom[] __devinitdata = { +static unsigned char aureon71_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -2140,7 +2140,7 @@ static const unsigned char aureon71_eeprom[] __devinitdata = { }; #define prodigy71_eeprom aureon71_eeprom -static const unsigned char prodigy71lt_eeprom[] __devinitdata = { +static unsigned char prodigy71lt_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -2158,7 +2158,7 @@ static const unsigned char prodigy71lt_eeprom[] __devinitdata = { #define prodigy71xt_eeprom prodigy71lt_eeprom /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_AUREON51_SKY, .name = "Terratec Aureon 5.1-Sky", diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h index 79e58e8..c253b8e 100644 --- a/sound/pci/ice1712/aureon.h +++ b/sound/pci/ice1712/aureon.h @@ -38,7 +38,7 @@ #define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */ #define VT1724_SUBDEVICE_PRODIGY71XT 0x36315441 /* PRODIGY 7.1 XT*/ -extern const struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; /* GPIO bits */ #define AUREON_CS8415_CS (1 << 22) diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 3f2aca2..0666cbc 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -1316,7 +1316,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = "ICE1724 EEPROM", .access = SNDRV_CTL_ELEM_ACCESS_READ, @@ -1429,7 +1429,7 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol, return (val != old); } -static const struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -1461,7 +1461,7 @@ static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1470,7 +1470,7 @@ static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = .get = snd_vt1724_spdif_maskc_get, }; -static const struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1515,7 +1515,7 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol, return old != val; } -static const struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* FIXME: the following conflict with IEC958 Playback Route */ @@ -1693,7 +1693,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Internal Clock", .info = snd_vt1724_pro_internal_clock_info, @@ -1732,7 +1732,7 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Locking", .info = snd_vt1724_pro_rate_locking_info, @@ -1771,7 +1771,7 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Reset", .info = snd_vt1724_pro_rate_reset_info, @@ -1890,7 +1890,7 @@ static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol, digital_route_shift(idx)); } -static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "H/W Playback Route", .info = snd_vt1724_pro_route_info, @@ -1898,7 +1898,7 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinit .put = snd_vt1724_pro_route_analog_put, }; -static const struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = snd_vt1724_pro_route_info, @@ -1934,7 +1934,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Peak", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, @@ -1946,9 +1946,9 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { * */ -static const struct snd_ice1712_card_info no_matched __devinitdata; +static struct snd_ice1712_card_info no_matched __devinitdata; -static const struct snd_ice1712_card_info *card_tables[] __devinitdata = { +static struct snd_ice1712_card_info *card_tables[] __devinitdata = { snd_vt1724_revo_cards, snd_vt1724_amp_cards, snd_vt1724_aureon_cards, @@ -2007,7 +2007,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, { const int dev = 0xa0; /* EEPROM device address */ unsigned int i, size; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (! modelname || ! *modelname) { ice->eeprom.subvendor = 0; @@ -2306,7 +2306,7 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, struct snd_card *card; struct snd_ice1712 *ice; int pcm_dev = 0, err; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (dev >= SNDRV_CARDS) return -ENODEV; diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index d88172f..6d3c633 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -125,7 +125,7 @@ static void juli_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) snd_akm4xxx_reset(ak, 0); } -static const struct snd_akm4xxx akm_juli_dac __devinitdata = { +static struct snd_akm4xxx akm_juli_dac __devinitdata = { .type = SND_AK4358, .num_dacs = 2, .ops = { @@ -206,7 +206,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char juli_eeprom[] __devinitdata = { +static unsigned char juli_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x20, /* clock 512, mpu401, 1xADC, 1xDACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ @@ -223,7 +223,7 @@ static const unsigned char juli_eeprom[] __devinitdata = { }; /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_JULI, .name = "ESI Juli@", diff --git a/sound/pci/ice1712/juli.h b/sound/pci/ice1712/juli.h index 1b9294f..d9f8534 100644 --- a/sound/pci/ice1712/juli.h +++ b/sound/pci/ice1712/juli.h @@ -5,6 +5,6 @@ #define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */ -extern const struct snd_ice1712_card_info snd_vt1724_juli_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_juli_cards[]; #endif /* __SOUND_JULI_H */ diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 0751718..40a9098 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -89,13 +89,13 @@ static const unsigned char wm_vol[256] = { #define WM_VOL_MAX (sizeof(wm_vol) - 1) #define WM_VOL_MUTE 0x8000 -static const struct snd_akm4xxx akm_phase22 __devinitdata = { +static struct snd_akm4xxx akm_phase22 __devinitdata = { .type = SND_AK4524, .num_dacs = 2, .num_adcs = 2, }; -static const struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { +static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { .caddr = 2, .cif = 1, .data_mask = 1 << 4, @@ -152,7 +152,7 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice) return 0; } -static const unsigned char phase22_eeprom[] __devinitdata = { +static unsigned char phase22_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */ @@ -168,7 +168,7 @@ static const unsigned char phase22_eeprom[] __devinitdata = { [ICE_EEP2_GPIO_STATE2] = 0x00, }; -static const unsigned char phase28_eeprom[] __devinitdata = { +static unsigned char phase28_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -700,7 +700,7 @@ static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ct static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); -static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { +static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -815,7 +815,7 @@ static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new wm_controls[] __devinitdata = { +static struct snd_kcontrol_new wm_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "PCM Playback Switch", @@ -870,7 +870,7 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice) return 0; } -const struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_PHASE22, .name = "Terratec PHASE 22", diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h index ad379a9..13e841b 100644 --- a/sound/pci/ice1712/phase.h +++ b/sound/pci/ice1712/phase.h @@ -31,7 +31,7 @@ #define VT1724_SUBDEVICE_PHASE28 0x3b154911 /* entry point */ -extern const struct snd_ice1712_card_info snd_vt1724_phase_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_phase_cards[]; /* PHASE28 GPIO bits */ #define PHASE28_SPI_MISO (1 << 21) diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 9552497..01c6945 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c @@ -571,7 +571,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1); * mixers */ -static const struct snd_kcontrol_new pontis_controls[] __devinitdata = { +static struct snd_kcontrol_new pontis_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | @@ -826,7 +826,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char pontis_eeprom[] __devinitdata = { +static unsigned char pontis_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ @@ -843,7 +843,7 @@ static const unsigned char pontis_eeprom[] __devinitdata = { }; /* entry point */ -const struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { { .subvendor = VT1720_SUBDEVICE_PONTIS_MS300, .name = "Pontis MS300", diff --git a/sound/pci/ice1712/pontis.h b/sound/pci/ice1712/pontis.h index 1a41825..d0d1378 100644 --- a/sound/pci/ice1712/pontis.h +++ b/sound/pci/ice1712/pontis.h @@ -28,6 +28,6 @@ #define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */ -extern const struct snd_ice1712_card_info snd_vt1720_pontis_cards[]; +extern struct snd_ice1712_card_info snd_vt1720_pontis_cards[]; #endif /* __SOUND_PONTIS_H */ diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index 31cc66e..9aad6b3 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -364,7 +364,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); * mixers */ -static const struct snd_kcontrol_new stac_controls[] __devinitdata = { +static struct snd_kcontrol_new stac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -506,7 +506,7 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char prodigy71_eeprom[] __devinitdata = { +static unsigned char prodigy71_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ @@ -524,7 +524,7 @@ static const unsigned char prodigy71_eeprom[] __devinitdata = { /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_PRODIGY192VE, .name = "Audiotrak Prodigy 192", diff --git a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h index 2fa2e62..94c824e 100644 --- a/sound/pci/ice1712/prodigy192.h +++ b/sound/pci/ice1712/prodigy192.h @@ -6,6 +6,6 @@ #define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */ -extern const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; #endif /* __SOUND_PRODIGY192_H */ diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 025a7e8..41f4026 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -219,7 +219,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = { }, }; -static const struct snd_akm4xxx akm_revo_front __devinitdata = { +static struct snd_akm4xxx akm_revo_front __devinitdata = { .type = SND_AK4381, .num_dacs = 2, .ops = { @@ -228,7 +228,7 @@ static const struct snd_akm4xxx akm_revo_front __devinitdata = { .dac_info = revo71_front, }; -static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { .caddr = 1, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -240,7 +240,7 @@ static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_revo_surround __devinitdata = { +static struct snd_akm4xxx akm_revo_surround __devinitdata = { .type = SND_AK4355, .idx_offset = 1, .num_dacs = 6, @@ -250,7 +250,7 @@ static const struct snd_akm4xxx akm_revo_surround __devinitdata = { .dac_info = revo71_surround, }; -static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { .caddr = 3, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -262,7 +262,7 @@ static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_revo51 __devinitdata = { +static struct snd_akm4xxx akm_revo51 __devinitdata = { .type = SND_AK4358, .num_dacs = 6, .ops = { @@ -271,7 +271,7 @@ static const struct snd_akm4xxx akm_revo51 __devinitdata = { .dac_info = revo51_dac, }; -static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -283,13 +283,13 @@ static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_revo51_adc __devinitdata = { +static struct snd_akm4xxx akm_revo51_adc __devinitdata = { .type = SND_AK5365, .num_adcs = 2, .adc_info = revo51_adc, }; -static const struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -324,7 +324,7 @@ static const struct snd_akm4xxx_dac_channel ap192_dac[] = { AK_DAC("PCM Playback Volume", 2) }; -static const struct snd_akm4xxx akm_ap192 __devinitdata = { +static struct snd_akm4xxx akm_ap192 __devinitdata = { .type = SND_AK4358, .num_dacs = 2, .ops = { @@ -333,7 +333,7 @@ static const struct snd_akm4xxx akm_ap192 __devinitdata = { .dac_info = ap192_dac, }; -static const struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -454,7 +454,7 @@ static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) return data; } -static int ap192_ak4114_init(struct snd_ice1712 *ice) +static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice) { static const unsigned char ak4114_init_vals[] = { AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, @@ -582,7 +582,7 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice) } /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_REVOLUTION71, .name = "M Audio Revolution-7.1", diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h index 2a24488..a3ba425 100644 --- a/sound/pci/ice1712/revo.h +++ b/sound/pci/ice1712/revo.h @@ -34,7 +34,7 @@ #define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236 /* entry point */ -extern const struct snd_ice1712_card_info snd_vt1724_revo_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; /* diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c index 72b060d..2395241 100644 --- a/sound/pci/ice1712/vt1720_mobo.c +++ b/sound/pci/ice1712/vt1720_mobo.c @@ -56,7 +56,7 @@ static int __devinit k8x800_add_controls(struct snd_ice1712 *ice) /* EEPROM image */ -static const unsigned char k8x800_eeprom[] __devinitdata = { +static unsigned char k8x800_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ [ICE_EEP2_I2S] = 0x00, /* - */ @@ -72,7 +72,7 @@ static const unsigned char k8x800_eeprom[] __devinitdata = { [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */ }; -static const unsigned char sn25p_eeprom[] __devinitdata = { +static unsigned char sn25p_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ [ICE_EEP2_I2S] = 0x00, /* - */ @@ -90,7 +90,7 @@ static const unsigned char sn25p_eeprom[] __devinitdata = { /* entry point */ -const struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { { .subvendor = VT1720_SUBDEVICE_K8X800, .name = "Albatron K8X800 Pro II", diff --git a/sound/pci/ice1712/vt1720_mobo.h b/sound/pci/ice1712/vt1720_mobo.h index 70af3ad..0b1b0ee 100644 --- a/sound/pci/ice1712/vt1720_mobo.h +++ b/sound/pci/ice1712/vt1720_mobo.h @@ -36,6 +36,6 @@ #define VT1720_SUBDEVICE_9CJS 0x0f272327 #define VT1720_SUBDEVICE_SN25P 0x97123650 -extern const struct snd_ice1712_card_info snd_vt1720_mobo_cards[]; +extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[]; #endif /* __SOUND_VT1720_MOBO_H */ diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c index 4a706b1..04e535c 100644 --- a/sound/pci/ice1712/wtm.c +++ b/sound/pci/ice1712/wtm.c @@ -409,7 +409,7 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, /* * Control tabs */ -static const struct snd_kcontrol_new stac9640_controls[] __devinitdata = { +static struct snd_kcontrol_new stac9640_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", -- cgit v0.10.2 From 2944275b146f4c0bb229a862bd8b3930c157d2a1 Mon Sep 17 00:00:00 2001 From: Rask Ingemann Lambertsen Date: Mon, 19 Mar 2007 11:38:11 +0100 Subject: [ALSA] ad1816a: Fix modprobe snd_mpu401 && modprobe snd_ad1816a The ad1816a driver fails if the mpu401 driver has been loaded first. This patch against linux 2.6.20 fixes it by just ignoring the MPU-401 device in that case, so that the rest of the sound card can be used. The ad1816a driver already handles the MPU-401 device being unavailable due to lack of resources in the same way. Signed-off-by: Rask Ingemann Lambertsen Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 5903450..fc88a31 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c @@ -129,8 +129,8 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar } acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL); if (acard->devmpu == NULL) { - kfree(cfg); - return -EBUSY; + mpu_port[dev] = -1; + snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n"); } pdev = acard->dev; @@ -162,6 +162,10 @@ static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acar dma2[dev] = pnp_dma(pdev, 1); irq[dev] = pnp_irq(pdev, 0); + if (acard->devmpu == NULL) { + kfree(cfg); + return 0; + } pdev = acard->devmpu; pnp_init_resource_table(cfg); -- cgit v0.10.2 From 02a5039fc72611801e20679d2030d627ed043463 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Mar 2007 11:42:18 +0100 Subject: [ALSA] hda-codec - Fix Macmini and Macbook pin configs Original idea from Nicolas Boichat . The pin configurations of Macmini and MacBook (1st generation, at least) seem identical with MacBook Pro (1st generation). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7a82413..6dd4822 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -524,12 +524,6 @@ static unsigned int d945gtp5_pin_configs[10] = { 0x02a19320, 0x40000100, }; -static unsigned int macbook_pin_configs[10] = { - 0x0321e230, 0x03a1e020, 0x400000fd, 0x9017e110, - 0x400000fe, 0x0381e021, 0x1345e240, 0x13c5e22e, - 0x400000fc, 0x400000fb, -}; - static unsigned int macbook_pro_v1_pin_configs[10] = { 0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010, 0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e, @@ -546,8 +540,8 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_D945_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, [STAC_D945GTP5] = d945gtp5_pin_configs, - [STAC_MACMINI] = d945gtp5_pin_configs, - [STAC_MACBOOK] = macbook_pin_configs, + [STAC_MACMINI] = macbook_pro_v1_pin_configs, + [STAC_MACBOOK] = macbook_pro_v1_pin_configs, [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, }; -- cgit v0.10.2 From e4b6088c8cf16781f7f7b887811b164daf625968 Mon Sep 17 00:00:00 2001 From: Julian Cable Date: Mon, 19 Mar 2007 11:44:40 +0100 Subject: [ALSA] hdsp - Add support for fine tuning of sample rate support to HDSP 9632 Add 'DDS Sample Rate Offset' control. Allows values in Hz from -5000 to +5000. The value is added to the nominal sample rate and written to the DDS register. Signed-off-by: Julian Cable Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 6540037..4b20f84 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -275,6 +275,11 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," #define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0) #define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1) #define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0) +/* RME says n = 104857600000000, but in the windows MADI driver, I see: + return 104857600000000 / rate; // 100 MHz + return 110100480000000 / rate; // 105 MHz +*/ +#define DDS_NUMERATOR 104857600000000ULL; /* = 2^20 * 10^8 */ #define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask) #define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1) @@ -1001,11 +1006,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate) else if (rate >= 56000) rate /= 2; - /* RME says n = 104857600000000, but in the windows MADI driver, I see: -// return 104857600000000 / rate; // 100 MHz - return 110100480000000 / rate; // 105 MHz - */ - n = 104857600000000ULL; /* = 2^20 * 10^8 */ + n = DDS_NUMERATOR; div64_32(&n, rate, &r); /* n should be less than 2^32 for being written to FREQ register */ snd_assert((n >> 32) == 0); @@ -3085,11 +3086,83 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn return 0; } +#define HDSP_DDS_OFFSET(xname, xindex) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdsp_info_dds_offset, \ + .get = snd_hdsp_get_dds_offset, \ + .put = snd_hdsp_put_dds_offset \ +} + +static int hdsp_dds_offset(struct hdsp *hdsp) +{ + u64 n; + u32 r; + unsigned int dds_value = hdsp->dds_value; + int system_sample_rate = hdsp->system_sample_rate; + + n = DDS_NUMERATOR; + /* + * dds_value = n / rate + * rate = n / dds_value + */ + div64_32(&n, dds_value, &r); + if (system_sample_rate >= 112000) + n *= 4; + else if (system_sample_rate >= 56000) + n *= 2; + return ((int)n) - system_sample_rate; +} + +static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz) +{ + int rate = hdsp->system_sample_rate + offset_hz; + hdsp_set_dds_value(hdsp, rate); + return 0; +} + +static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = -5000; + uinfo->value.integer.max = 5000; + return 0; +} + +static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp); + return 0; +} + +static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.enumerated.item[0]; + spin_lock_irq(&hdsp->lock); + if (val != hdsp_dds_offset(hdsp)) + change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0; + else + change = 0; + spin_unlock_irq(&hdsp->lock); + return change; +} + static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { HDSP_DA_GAIN("DA Gain", 0), HDSP_AD_GAIN("AD Gain", 0), HDSP_PHONE_GAIN("Phones Gain", 0), -HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0) +HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0), +HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) }; static struct snd_kcontrol_new snd_hdsp_controls[] = { -- cgit v0.10.2 From 83c51c0ab08f55468d8f5444ff2f70a36841a21f Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Tue, 20 Mar 2007 11:33:46 +0100 Subject: [ALSA] isa_bus device/driver naming isa_bus: delete snd_ prefix from the (sysfs visible) device/driver names. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index 456156d..214d65d 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -601,7 +601,7 @@ static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n) } #endif -#define CMI8330_DRIVER "snd_cmi8330" +#define DEV_NAME "cmi8330" static struct isa_driver snd_cmi8330_driver = { .match = snd_cmi8330_isa_match, @@ -612,7 +612,7 @@ static struct isa_driver snd_cmi8330_driver = { .resume = snd_cmi8330_isa_resume, #endif .driver = { - .name = CMI8330_DRIVER + .name = DEV_NAME }, }; diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 7d9d4d5..87f1392 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -75,10 +75,10 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4235}," #ifdef CS4232 #define IDENT "CS4232" -#define CS423X_DRIVER "snd_cs4232" +#define DEV_NAME "cs4232" #else #define IDENT "CS4236+" -#define CS423X_DRIVER "snd_cs4236" +#define DEV_NAME "cs4236" #endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ @@ -630,7 +630,7 @@ static struct isa_driver cs423x_isa_driver = { .resume = snd_cs423x_isa_resume, #endif .driver = { - .name = CS423X_DRIVER + .name = DEV_NAME }, }; diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 12b61af..d2a9c7d 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -2318,7 +2318,7 @@ static int snd_es18xx_isa_resume(struct device *dev, unsigned int n) } #endif -#define ES18XX_DRIVER "snd_es18xx" +#define DEV_NAME "es18xx" static struct isa_driver snd_es18xx_isa_driver = { .match = snd_es18xx_isa_match, @@ -2329,7 +2329,7 @@ static struct isa_driver snd_es18xx_isa_driver = { .resume = snd_es18xx_isa_resume, #endif .driver = { - .name = ES18XX_DRIVER + .name = DEV_NAME }, }; diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index a0d2f8f..708783d 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c @@ -358,7 +358,7 @@ static int __devexit snd_gusmax_remove(struct device *devptr, unsigned int dev) return 0; } -#define GUSMAX_DRIVER "snd_gusmax" +#define DEV_NAME "gusmax" static struct isa_driver snd_gusmax_driver = { .match = snd_gusmax_match, @@ -366,7 +366,7 @@ static struct isa_driver snd_gusmax_driver = { .remove = __devexit_p(snd_gusmax_remove), /* FIXME: suspend/resume */ .driver = { - .name = GUSMAX_DRIVER + .name = DEV_NAME }, }; diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 50a812f..48743eb 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -947,7 +947,7 @@ static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n) } #endif -#define OPL3SA2_DRIVER "snd_opl3sa2" +#define DEV_NAME "opl3sa2" static struct isa_driver snd_opl3sa2_isa_driver = { .match = snd_opl3sa2_isa_match, @@ -958,7 +958,7 @@ static struct isa_driver snd_opl3sa2_isa_driver = { .resume = snd_opl3sa2_isa_resume, #endif .driver = { - .name = OPL3SA2_DRIVER + .name = DEV_NAME }, }; diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 33471bd..cd29b30 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -137,8 +137,6 @@ struct snd_miro { static void snd_miro_proc_init(struct snd_miro * miro); -#define DRIVER_NAME "snd-miro" - static char * snd_opti9xx_names[] = { "unkown", "82C928", "82C929", @@ -1423,13 +1421,15 @@ static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev) return 0; } +#define DEV_NAME "miro" + static struct isa_driver snd_miro_driver = { .match = snd_miro_match, .probe = snd_miro_probe, .remove = __devexit_p(snd_miro_remove), /* FIXME: suspend/resume */ .driver = { - .name = DRIVER_NAME + .name = DEV_NAME }, }; diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 95d0ab1..60c120f 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -280,10 +280,10 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids); #endif /* CONFIG_PNP */ #ifdef OPTi93X -#define DRIVER_NAME "snd-card-opti93x" +#define DEV_NAME "opti93x" #else -#define DRIVER_NAME "snd-card-opti92x" -#endif /* OPTi93X */ +#define DEV_NAME "opti92x" +#endif static char * snd_opti9xx_names[] = { "unkown", @@ -1289,7 +1289,7 @@ static int snd_opti93x_create(struct snd_card *card, struct snd_opti9xx *chip, } codec->dma2 = chip->dma2; - if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DRIVER_NAME" - WSS", codec)) { + if (request_irq(chip->irq, snd_opti93x_interrupt, IRQF_DISABLED, DEV_NAME" - WSS", codec)) { snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq); snd_opti93x_free(codec); return -EBUSY; @@ -2015,7 +2015,7 @@ static struct isa_driver snd_opti9xx_driver = { .remove = __devexit_p(snd_opti9xx_isa_remove), /* FIXME: suspend/resume */ .driver = { - .name = DRIVER_NAME + .name = DEV_NAME }, }; diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 8b734a2..2a19b0a 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c @@ -615,9 +615,9 @@ static int snd_sb16_isa_resume(struct device *dev, unsigned int n) #endif #ifdef SNDRV_SBAWE -#define SND_SB16_DRIVER "snd_sbawe" +#define DEV_NAME "sbawe" #else -#define SND_SB16_DRIVER "snd_sb16" +#define DEV_NAME "sb16" #endif static struct isa_driver snd_sb16_isa_driver = { @@ -629,7 +629,7 @@ static struct isa_driver snd_sb16_isa_driver = { .resume = snd_sb16_isa_resume, #endif .driver = { - .name = SND_SB16_DRIVER + .name = DEV_NAME }, }; diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index b7de1bc..a1b3786 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c @@ -239,7 +239,7 @@ static int snd_sb8_resume(struct device *dev, unsigned int n) } #endif -#define SND_SB8_DRIVER "snd_sb8" +#define DEV_NAME "sb8" static struct isa_driver snd_sb8_driver = { .match = snd_sb8_match, @@ -250,7 +250,7 @@ static struct isa_driver snd_sb8_driver = { .resume = snd_sb8_resume, #endif .driver = { - .name = SND_SB8_DRIVER + .name = DEV_NAME }, }; diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c index 19e0b0e..922519d 100644 --- a/sound/isa/sgalaxy.c +++ b/sound/isa/sgalaxy.c @@ -334,7 +334,7 @@ static int snd_sgalaxy_resume(struct device *pdev, unsigned int n) } #endif -#define SND_SGALAXY_DRIVER "snd_sgalaxy" +#define DEV_NAME "sgalaxy" static struct isa_driver snd_sgalaxy_driver = { .match = snd_sgalaxy_match, @@ -345,7 +345,7 @@ static struct isa_driver snd_sgalaxy_driver = { .resume = snd_sgalaxy_resume, #endif .driver = { - .name = SND_SGALAXY_DRIVER + .name = DEV_NAME }, }; diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index 369de44..08c1497 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c @@ -1296,7 +1296,7 @@ static int __devexit snd_sscape_remove(struct device *devptr, unsigned int dev) return 0; } -#define SSCAPE_DRIVER "snd_sscape" +#define DEV_NAME "sscape" static struct isa_driver snd_sscape_driver = { .match = snd_sscape_match, @@ -1304,7 +1304,7 @@ static struct isa_driver snd_sscape_driver = { .remove = __devexit_p(snd_sscape_remove), /* FIXME: suspend/resume */ .driver = { - .name = SSCAPE_DRIVER + .name = DEV_NAME }, }; diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index 6f14327..ae2038e 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -633,7 +633,7 @@ static int __devexit snd_wavefront_isa_remove(struct device *devptr, return 0; } -#define WAVEFRONT_DRIVER "snd_wavefront" +#define DEV_NAME "wavefront" static struct isa_driver snd_wavefront_driver = { .match = snd_wavefront_isa_match, @@ -641,7 +641,7 @@ static struct isa_driver snd_wavefront_driver = { .remove = __devexit_p(snd_wavefront_isa_remove), /* FIXME: suspend, resume */ .driver = { - .name = WAVEFRONT_DRIVER + .name = DEV_NAME }, }; -- cgit v0.10.2 From 97a1dd5bee9edab5172553cbdcfc858393814556 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 21 Mar 2007 11:54:04 +0100 Subject: [ALSA] fix SND_SOC Kconfig The new ALSA 'SOC' support has bogus Kconfig ... it should not be presenting anything AT91-related except on AT91, or anything PXA-related except on PXA. Right now, x86 sees both of those menus, as do all other platforms. This patch removes needless Kconfig layering, and the related inappropriate choice presentation. Signed-off-by: David Brownell Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 03e04ae..23a5c3b 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -22,12 +22,9 @@ config SND_SOC will be called snd-soc-core. # All the supported Soc's -menu "SoC Platforms" -depends on SND_SOC source "sound/soc/at91/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/s3c24xx/Kconfig" -endmenu # Supported codecs source "sound/soc/codecs/Kconfig" diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig index a5b2558..e41e75e 100644 --- a/sound/soc/at91/Kconfig +++ b/sound/soc/at91/Kconfig @@ -1,5 +1,3 @@ -menu "SoC Audio for the Atmel AT91" - config SND_AT91_SOC tristate "SoC Audio for the Atmel AT91 System-on-Chip" depends on ARCH_AT91 && SND_SOC @@ -27,5 +25,3 @@ config SND_AT91_SOC_ETI_SLAVE help Say Y if you want to run with the AT91 SSC generating the BCLK and LRC signals on Endrelia boards. - -endmenu diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index b9ab3b8..a83e229 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -1,5 +1,3 @@ -menu "SoC Audio for the Intel PXA2xx" - config SND_PXA2XX_SOC tristate "SoC Audio for the Intel PXA2xx chip" depends on ARCH_PXA && SND_SOC @@ -55,5 +53,3 @@ config SND_PXA2XX_SOC_TOSA help Say Y if you want to add support for SoC audio on Sharp Zaurus SL-C6000x models (Tosa). - -endmenu diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index bb6e00a..044a371 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -1,5 +1,3 @@ -menu "SoC Audio for the Samsung S3C24XX" - config SND_S3C24XX_SOC tristate "SoC Audio for the Samsung S3C24XX chips" depends on ARCH_S3C2410 && SND_SOC @@ -10,6 +8,3 @@ config SND_S3C24XX_SOC config SND_S3C24XX_SOC_I2S tristate - -endmenu - -- cgit v0.10.2 From 4505179c73197c39272e8e66a172ab788009e07e Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Wed, 21 Mar 2007 12:05:06 +0100 Subject: [ALSA] Fix alsa-devel ML address This replaces all occurences of alsa-devel@lists.s[ource]f[orge].net that a simple recursive grep found in the current HG ALSA repos by alsa-devel@alsa-project.org. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 4d92a3e6..0dbc95d 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -2051,4 +2051,4 @@ Links and Addresses https://bugtrack.alsa-project.org/bugs/ ALSA Developers ML - mailto:alsa-devel@lists.sourceforge.net + mailto:alsa-devel@alsa-project.org diff --git a/Documentation/sound/alsa/Bt87x.txt b/Documentation/sound/alsa/Bt87x.txt index 11edb2f..f158cde 100644 --- a/Documentation/sound/alsa/Bt87x.txt +++ b/Documentation/sound/alsa/Bt87x.txt @@ -36,8 +36,8 @@ recorded data is not right, try to specify the digital_rate option with other values than the default 32000 (often it's 44100 or 64000). If you have an unknown card, please mail the ID and board name to -, regardless of whether audio capture works or -not, so that future versions of this driver know about your card. +, regardless of whether audio capture works +or not, so that future versions of this driver know about your card. Audio modes diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 9eb95a2..6523ba0 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -835,7 +835,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) pci->device, pci->subsystem_vendor, pci->subsystem_device); snd_printk(KERN_DEBUG "please mail id, board name, and, " "if it works, the correct digital_rate option to " - "\n"); + "\n"); return 32000; /* default rate */ } diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 2ae539b..bef1f6d 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -3107,7 +3107,7 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n"); snd_printk(KERN_ERR " broken or not working on your soundcard upon\n"); - snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n"); + snd_printk(KERN_ERR " this message please report to alsa-devel@alsa-project.org\n"); return -EIO; #endif -- cgit v0.10.2 From 19a982b69442d39b3bb6e710677320182480576b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 21 Mar 2007 15:14:35 +0100 Subject: [ALSA] hda-intel - Probe additional slots only if necessary Probing the codec slots on ATI controller causes problems on some devices like Acer laptops. On these devices, reading from codec slot 3 results in the communication failure with the codec chip. Meanwhile, some laptops (e.g. Gateway) have the codec connection only on slot 3, and probing this slot is mandatory for them. The patch improves the probing robustness. The additional slots are now checked only when no codecs are found in the primary three slots. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 517a8d7..5e478b9 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -198,6 +198,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define RIRB_INT_MASK 0x05 /* STATESTS int mask: SD2,SD1,SD0 */ +#define AZX_MAX_CODECS 3 #define STATESTS_INT_MASK 0x07 /* SD_CTL bits */ @@ -991,7 +992,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) return err; codecs = 0; - for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) { + for (c = 0; c < AZX_MAX_CODECS; c++) { if ((chip->codec_mask & (1 << c)) & probe_mask) { err = snd_hda_codec_new(chip->bus, c, NULL); if (err < 0) @@ -999,7 +1000,18 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) codecs++; } } - if (! codecs) { + if (!codecs) { + /* probe additional slots if no codec is found */ + for (; c < azx_max_codecs[chip->driver_type]; c++) { + if ((chip->codec_mask & (1 << c)) & probe_mask) { + err = snd_hda_codec_new(chip->bus, c, NULL); + if (err < 0) + continue; + codecs++; + } + } + } + if (!codecs) { snd_printk(KERN_ERR SFX "no codecs initialized\n"); return -ENXIO; } -- cgit v0.10.2 From 1aba2bc32144ed13f1c0e581471fe943e738ff42 Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Thu, 22 Mar 2007 01:02:58 +0100 Subject: [ALSA] hda-codec - Fix front/rear mic inputs on AD1986A codec Fix the front/rear mic inputs on ASUS M2NPV-VM board with AD1986A codec chip (3stack model). Signed-off-by: Andrea Arcangeli Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index f94f1f22..9c241cc 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -741,8 +741,9 @@ static struct hda_verb ad1986a_init_verbs[] = { /* additional verbs for 3-stack model */ static struct hda_verb ad1986a_3st_init_verbs[] = { - /* Mic and line-in selectors */ - {0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, + /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */ + {0x0f, AC_VERB_SET_CONNECT_SEL, 0x4}, + /* Line-in selectors */ {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, { } /* end */ }; -- cgit v0.10.2 From e24a121aa1070fc91b6461b8b88bb6ffa61b4b49 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Mon, 26 Mar 2007 12:49:45 +0200 Subject: [ALSA] azt3328.c: small cleanup patch - change 'PCM' mixer control (pre/post 3D) to 'PCM Output Route' - improve snd_azf3328_debug_show_ports - less aggressive module init message - document Bass/Treble non-bug (prompted by user report - Thank You!!) - add some items to card description - add some I/O register documentation - enhance copyright Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index e7daddd..36d3666 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -1,6 +1,6 @@ /* * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). - * Copyright (C) 2002, 2005 by Andreas Mohr + * Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr * * Framework borrowed from Bart Hartgers's als4000.c. * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), @@ -52,6 +52,9 @@ * - full duplex 16bit playback/record at independent sampling rate * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr?? * - game port (legacy address support) + * - builtin 3D enhancement (said to be YAMAHA Ymersion) + * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven + * features supported) * - built-in General DirectX timer having a 20 bits counter * with 1us resolution (see below!) * - I2S serial port for external DAC @@ -94,6 +97,10 @@ * * BUGS * - full-duplex might *still* be problematic, not fully tested recently + * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated + * if you set PCM output switch to "pre 3D" instead of "post 3D". + * If this can't be set, then get a mixer application that Isn't Stupid (tm) + * (e.g. kmix, gamix) - unfortunately several are!! * * TODO * - test MPU401 MIDI playback etc. @@ -652,7 +659,7 @@ static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = { AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1), AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8), AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9), - AZF3328_MIXER_ENUM("PCM", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */ + AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */ AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0), AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0), AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0), @@ -1369,7 +1376,6 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream) struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); snd_azf3328_dbgcallenter(); - chip->playback_substream = NULL; snd_azf3328_dbgcallleave(); return 0; @@ -1660,10 +1666,10 @@ snd_azf3328_test_bit(unsigned int reg, int bit) } #endif +#if DEBUG_MISC static void snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) { -#if DEBUG_MISC u16 tmp; snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq); @@ -1673,10 +1679,16 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) for (tmp=0; tmp <= 0x01; tmp += 1) snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp)); - for (tmp = 0; tmp <= 0x6E; tmp += 2) - snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp)); -#endif + for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2) + snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp)); + + for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2) + snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp)); } +#else +static inline void +snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {} +#endif static int __devinit snd_azf3328_create(struct snd_card *card, @@ -1842,8 +1854,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) #ifdef MODULE printk( -"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n" -"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n" +"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n" +"azt3328: Hardware was completely undocumented, unfortunately.\n" "azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n" "azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n", 1024000 / seqtimer_scaling, seqtimer_scaling); diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h index b4f3e3c..679fa99 100644 --- a/sound/pci/azt3328.h +++ b/sound/pci/azt3328.h @@ -106,8 +106,8 @@ #define IRQ_RECORDING 0x0002 #define IRQ_MPU401 0x0010 #define IRQ_TIMER 0x0020 /* DirectX timer */ - #define IRQ_UNKNOWN1 0x0040 /* probably unused */ - #define IRQ_UNKNOWN2 0x0080 /* probably unused */ + #define IRQ_UNKNOWN1 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */ + #define IRQ_UNKNOWN2 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */ #define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ #define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */ #define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */ -- cgit v0.10.2 From 523f1dce37434a9a6623bf46e7893e2b4b10ac3c Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 26 Mar 2007 19:11:24 +0200 Subject: [ALSA] Add Native Instrument usb audio device support Add snd-usb-caiaq driver to support caiaq usb-audio devices from Native Instrument: * Native Instruments RigKontrol2 * Native Instruments Kore Controller * Native Instruments Audio Kontrol 1 * Native Instruments Audio 8 DJ Signed-off-by: Daniel Mack Signed-off-by: Karsten Wiese Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 0dbc95d..62f9e4c 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1697,6 +1697,17 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. This module supports multiple devices, autoprobe and hotplugging. + Module snd-usb-caiaq + -------------------- + + Module for caiaq UB audio interfaces, + * Native Instruments RigKontrol2 + * Native Instruments Kore Controller + * Native Instruments Audio Kontrol 1 + * Native Instruments Audio 8 DJ + + This module supports multiple devices, autoprobe and hotplugging. + Module snd-usb-usx2y -------------------- diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index f05d02f..315360f 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig @@ -29,5 +29,33 @@ config SND_USB_USX2Y To compile this driver as a module, choose M here: the module will be called snd-usb-usx2y. +config SND_USB_CAIAQ + tristate "Native Instruments USB audio devices" + depends on SND && USB + select SND_HWDEP + select SND_RAWMIDI + select SND_PCM + help + Say Y here to include support for caiaq USB audio interfaces, + namely: + + * Native Instruments RigKontrol2 + * Native Instruments Kore Controller + * Native Instruments Audio Kontrol 1 + * Native Instruments Audio 8 DJ + + To compile this driver as a module, choose M here: the module + will be called snd-usb-caiaq. + +config SND_USB_CAIAQ_INPUT + bool "enable input device for controllers" + depends on SND_USB_CAIAQ + help + Say Y here to support input controllers like buttons, knobs, + alpha dials and analog pedals on the following products: + + * Native Instruments RigKontrol2 + * Native Instruments Audio Kontrol 1 + endmenu diff --git a/sound/usb/Makefile b/sound/usb/Makefile index 2c1dc11..aa252ef 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile @@ -9,4 +9,4 @@ snd-usb-lib-objs := usbmidi.o obj-$(CONFIG_SND_USB_AUDIO) += snd-usb-audio.o snd-usb-lib.o obj-$(CONFIG_SND_USB_USX2Y) += snd-usb-lib.o -obj-$(CONFIG_SND) += usx2y/ +obj-$(CONFIG_SND) += usx2y/ caiaq/ diff --git a/sound/usb/caiaq/Makefile b/sound/usb/caiaq/Makefile new file mode 100644 index 0000000..455c8c5 --- /dev/null +++ b/sound/usb/caiaq/Makefile @@ -0,0 +1,3 @@ +snd-usb-caiaq-objs := caiaq-device.o caiaq-audio.o caiaq-midi.o caiaq-input.o + +obj-$(CONFIG_SND_USB_CAIAQ) += snd-usb-caiaq.o diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c new file mode 100644 index 0000000..e80c8db --- /dev/null +++ b/sound/usb/caiaq/caiaq-audio.c @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2006,2007 Daniel Mack, Karsten Wiese + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_SND_USB_CAIAQ_INPUT +#include +#endif + +#include "caiaq-device.h" +#include "caiaq-audio.h" + +#define N_URBS 32 +#define CLOCK_DRIFT_TOLERANCE 5 +#define FRAMES_PER_URB 8 +#define BYTES_PER_FRAME 512 +#define CHANNELS_PER_STREAM 2 +#define BYTES_PER_SAMPLE 3 +#define BYTES_PER_SAMPLE_USB 4 +#define MAX_BUFFER_SIZE (128*1024) + +#define ENDPOINT_CAPTURE 2 +#define ENDPOINT_PLAYBACK 6 + +#define MAKE_CHECKBYTE(dev,stream,i) \ + (stream << 1) | (~(i / (dev->n_streams * BYTES_PER_SAMPLE_USB)) & 1) + +static struct snd_pcm_hardware snd_usb_caiaq_pcm_hardware = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER), + .formats = SNDRV_PCM_FMTBIT_S24_3BE, + .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000), + .rate_min = 44100, + .rate_max = 0, /* will overwrite later */ + .channels_min = CHANNELS_PER_STREAM, + .channels_max = CHANNELS_PER_STREAM, + .buffer_bytes_max = MAX_BUFFER_SIZE, + .period_bytes_min = 4096, + .period_bytes_max = MAX_BUFFER_SIZE, + .periods_min = 1, + .periods_max = 1024, +}; + +static void +activate_substream(struct snd_usb_caiaqdev *dev, + struct snd_pcm_substream *sub) +{ + if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) + dev->sub_playback[sub->number] = sub; + else + dev->sub_capture[sub->number] = sub; +} + +static void +deactivate_substream(struct snd_usb_caiaqdev *dev, + struct snd_pcm_substream *sub) +{ + if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) + dev->sub_playback[sub->number] = NULL; + else + dev->sub_capture[sub->number] = NULL; +} + +static int +all_substreams_zero(struct snd_pcm_substream **subs) +{ + int i; + for (i = 0; i < MAX_STREAMS; i++) + if (subs[i] != NULL) + return 0; + return 1; +} + +static int stream_start(struct snd_usb_caiaqdev *dev) +{ + int i, ret; + + debug("stream_start(%p)\n", dev); + spin_lock_irq(&dev->spinlock); + if (dev->streaming) { + spin_unlock_irq(&dev->spinlock); + return -EINVAL; + } + + dev->input_panic = 0; + dev->output_panic = 0; + dev->first_packet = 1; + dev->streaming = 1; + + for (i = 0; i < N_URBS; i++) { + ret = usb_submit_urb(dev->data_urbs_in[i], GFP_ATOMIC); + if (ret) { + log("unable to trigger initial read #%d! (ret = %d)\n", + i, ret); + dev->streaming = 0; + spin_unlock_irq(&dev->spinlock); + return -EPIPE; + } + } + + spin_unlock_irq(&dev->spinlock); + return 0; +} + +static void stream_stop(struct snd_usb_caiaqdev *dev) +{ + int i; + + debug("stream_stop(%p)\n", dev); + if (!dev->streaming) + return; + + dev->streaming = 0; + for (i = 0; i < N_URBS; i++) { + usb_unlink_urb(dev->data_urbs_in[i]); + usb_unlink_urb(dev->data_urbs_out[i]); + } +} + +static int snd_usb_caiaq_substream_open(struct snd_pcm_substream *substream) +{ + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); + debug("snd_usb_caiaq_substream_open(%p)\n", substream); + substream->runtime->hw = dev->pcm_info; + snd_pcm_limit_hw_rates(substream->runtime); + return 0; +} + +static int snd_usb_caiaq_substream_close(struct snd_pcm_substream *substream) +{ + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); + + debug("snd_usb_caiaq_substream_close(%p)\n", substream); + if (all_substreams_zero(dev->sub_playback) && + all_substreams_zero(dev->sub_capture)) { + /* when the last client has stopped streaming, + * all sample rates are allowed again */ + stream_stop(dev); + dev->pcm_info.rates = dev->samplerates; + } + + return 0; +} + +static int snd_usb_caiaq_pcm_hw_params(struct snd_pcm_substream *sub, + struct snd_pcm_hw_params *hw_params) +{ + debug("snd_usb_caiaq_pcm_hw_params(%p)\n", sub); + return snd_pcm_lib_malloc_pages(sub, params_buffer_bytes(hw_params)); +} + +static int snd_usb_caiaq_pcm_hw_free(struct snd_pcm_substream *sub) +{ + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); + debug("snd_usb_caiaq_pcm_hw_free(%p)\n", sub); + spin_lock_irq(&dev->spinlock); + deactivate_substream(dev, sub); + spin_unlock_irq(&dev->spinlock); + return snd_pcm_lib_free_pages(sub); +} + +/* this should probably go upstream */ +#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12 +#error "Change this table" +#endif + +static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100, + 48000, 64000, 88200, 96000, 176400, 192000 }; + +static int snd_usb_caiaq_pcm_prepare(struct snd_pcm_substream *substream) +{ + int bytes_per_sample, bpp, ret, i; + int index = substream->number; + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + + debug("snd_usb_caiaq_pcm_prepare(%p)\n", substream); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dev->audio_out_buf_pos[index] = BYTES_PER_SAMPLE + 1; + else + dev->audio_in_buf_pos[index] = 0; + + if (dev->streaming) + return 0; + + /* the first client that opens a stream defines the sample rate + * setting for all subsequent calls, until the last client closed. */ + for (i=0; i < ARRAY_SIZE(rates); i++) + if (runtime->rate == rates[i]) + dev->pcm_info.rates = 1 << i; + + snd_pcm_limit_hw_rates(runtime); + + bytes_per_sample = BYTES_PER_SAMPLE; + if (dev->spec.data_alignment == 2) + bytes_per_sample++; + + bpp = ((runtime->rate / 8000) + CLOCK_DRIFT_TOLERANCE) + * bytes_per_sample * CHANNELS_PER_STREAM * dev->n_streams; + + ret = snd_usb_caiaq_set_audio_params(dev, runtime->rate, + runtime->sample_bits, bpp); + if (ret) + return ret; + + ret = stream_start(dev); + if (ret) + return ret; + + dev->output_running = 0; + wait_event_timeout(dev->prepare_wait_queue, dev->output_running, HZ); + if (!dev->output_running) { + stream_stop(dev); + return -EPIPE; + } + + return 0; +} + +static int snd_usb_caiaq_pcm_trigger(struct snd_pcm_substream *sub, int cmd) +{ + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + spin_lock(&dev->spinlock); + activate_substream(dev, sub); + spin_unlock(&dev->spinlock); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + spin_lock(&dev->spinlock); + deactivate_substream(dev, sub); + spin_unlock(&dev->spinlock); + break; + default: + return -EINVAL; + } + + return 0; +} + +static snd_pcm_uframes_t +snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) +{ + int index = sub->number; + struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); + + if (dev->input_panic || dev->output_panic) + return SNDRV_PCM_POS_XRUN; + + if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) + return bytes_to_frames(sub->runtime, + dev->audio_out_buf_pos[index]); + else + return bytes_to_frames(sub->runtime, + dev->audio_in_buf_pos[index]); +} + +/* operators for both playback and capture */ +static struct snd_pcm_ops snd_usb_caiaq_ops = { + .open = snd_usb_caiaq_substream_open, + .close = snd_usb_caiaq_substream_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_usb_caiaq_pcm_hw_params, + .hw_free = snd_usb_caiaq_pcm_hw_free, + .prepare = snd_usb_caiaq_pcm_prepare, + .trigger = snd_usb_caiaq_pcm_trigger, + .pointer = snd_usb_caiaq_pcm_pointer +}; + +static void check_for_elapsed_periods(struct snd_usb_caiaqdev *dev, + struct snd_pcm_substream **subs) +{ + int stream, pb, *cnt; + struct snd_pcm_substream *sub; + + for (stream = 0; stream < dev->n_streams; stream++) { + sub = subs[stream]; + if (!sub) + continue; + + pb = frames_to_bytes(sub->runtime, + sub->runtime->period_size); + cnt = (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) ? + &dev->period_out_count[stream] : + &dev->period_in_count[stream]; + + if (*cnt >= pb) { + snd_pcm_period_elapsed(sub); + *cnt %= pb; + } + } +} + +static void read_in_urb_mode0(struct snd_usb_caiaqdev *dev, + const struct urb *urb, + const struct usb_iso_packet_descriptor *iso) +{ + unsigned char *usb_buf = urb->transfer_buffer + iso->offset; + struct snd_pcm_substream *sub; + int stream, i; + + if (all_substreams_zero(dev->sub_capture)) + return; + + spin_lock(&dev->spinlock); + + for (i = 0; i < iso->actual_length;) { + for (stream = 0; stream < dev->n_streams; stream++, i++) { + sub = dev->sub_capture[stream]; + if (sub) { + struct snd_pcm_runtime *rt = sub->runtime; + char *audio_buf = rt->dma_area; + int sz = frames_to_bytes(rt, rt->buffer_size); + audio_buf[dev->audio_in_buf_pos[stream]++] + = usb_buf[i]; + dev->period_in_count[stream]++; + if (dev->audio_in_buf_pos[stream] == sz) + dev->audio_in_buf_pos[stream] = 0; + } + } + } + + spin_unlock(&dev->spinlock); +} + +static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, + const struct urb *urb, + const struct usb_iso_packet_descriptor *iso) +{ + unsigned char *usb_buf = urb->transfer_buffer + iso->offset; + unsigned char check_byte; + struct snd_pcm_substream *sub; + int stream, i; + + spin_lock(&dev->spinlock); + + for (i = 0; i < iso->actual_length;) { + if (i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == 0) { + for (stream = 0; + stream < dev->n_streams; + stream++, i++) { + if (dev->first_packet) + continue; + + check_byte = MAKE_CHECKBYTE(dev, stream, i); + + if ((usb_buf[i] & 0x3f) != check_byte) + dev->input_panic = 1; + + if (usb_buf[i] & 0x80) + dev->output_panic = 1; + } + } + dev->first_packet = 0; + + for (stream = 0; stream < dev->n_streams; stream++, i++) { + sub = dev->sub_capture[stream]; + if (sub) { + struct snd_pcm_runtime *rt = sub->runtime; + char *audio_buf = rt->dma_area; + int sz = frames_to_bytes(rt, rt->buffer_size); + audio_buf[dev->audio_in_buf_pos[stream]++] + = usb_buf[i]; + dev->period_in_count[stream]++; + if (dev->audio_in_buf_pos[stream] == sz) + dev->audio_in_buf_pos[stream] = 0; + } + } + } + + spin_unlock(&dev->spinlock); +} + +static void read_in_urb(struct snd_usb_caiaqdev *dev, + const struct urb *urb, + const struct usb_iso_packet_descriptor *iso) +{ + if (!dev->streaming) + return; + + switch (dev->spec.data_alignment) { + case 0: + read_in_urb_mode0(dev, urb, iso); + break; + case 2: + read_in_urb_mode2(dev, urb, iso); + break; + } + + if (dev->input_panic || dev->output_panic) { + debug("streaming error detected %s %s\n", + dev->input_panic ? "(input)" : "", + dev->output_panic ? "(output)" : ""); + } + + check_for_elapsed_periods(dev, dev->sub_capture); +} + +static void fill_out_urb(struct snd_usb_caiaqdev *dev, + struct urb *urb, + const struct usb_iso_packet_descriptor *iso) +{ + unsigned char *usb_buf = urb->transfer_buffer + iso->offset; + struct snd_pcm_substream *sub; + int stream, i; + + spin_lock(&dev->spinlock); + + for (i = 0; i < iso->length;) { + for (stream = 0; stream < dev->n_streams; stream++) { + sub = dev->sub_playback[stream]; + if (sub) { + struct snd_pcm_runtime *rt = sub->runtime; + char *audio_buf = rt->dma_area; + int sz = frames_to_bytes(rt, rt->buffer_size); + usb_buf[i++] + = audio_buf[dev->audio_out_buf_pos[stream]++]; + dev->audio_out_buf_pos[stream]++; + if (dev->audio_out_buf_pos[stream] == sz) + dev->audio_out_buf_pos[stream] = 0; + } else + usb_buf[i++] = 0; + + /* fill in the check bytes */ + if (dev->spec.data_alignment == 2 && + i % (dev->n_streams * BYTES_PER_SAMPLE_USB) == + (dev->n_streams * CHANNELS_PER_STREAM)) + for (stream = 0; stream < dev->n_streams; stream++, i++) + usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); + } + } + + spin_unlock(&dev->spinlock); + check_for_elapsed_periods(dev, dev->sub_playback); +} + +static void read_completed(struct urb *urb) +{ + struct snd_usb_caiaq_cb_info *info = urb->context; + struct snd_usb_caiaqdev *dev; + struct urb *out; + int frame, len, send_it = 0, outframe = 0; + + if (urb->status || !info) + return; + + dev = info->dev; + if (!dev->streaming) + return; + + out = dev->data_urbs_out[info->index]; + + /* read the recently received packet and send back one which has + * the same layout */ + for (frame = 0; frame < FRAMES_PER_URB; frame++) { + if (urb->iso_frame_desc[frame].status) + continue; + + len = urb->iso_frame_desc[outframe].actual_length; + out->iso_frame_desc[outframe].length = len; + out->iso_frame_desc[outframe].actual_length = 0; + out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame; + + if (len > 0) { + fill_out_urb(dev, out, &out->iso_frame_desc[outframe]); + read_in_urb(dev, urb, &urb->iso_frame_desc[frame]); + send_it = 1; + } + + outframe++; + } + + if (send_it) { + out->number_of_packets = FRAMES_PER_URB; + out->transfer_flags = URB_ISO_ASAP; + usb_submit_urb(out, GFP_ATOMIC); + } + + /* re-submit inbound urb */ + for (frame = 0; frame < FRAMES_PER_URB; frame++) { + urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; + urb->iso_frame_desc[frame].length = BYTES_PER_FRAME; + urb->iso_frame_desc[frame].actual_length = 0; + } + + urb->number_of_packets = FRAMES_PER_URB; + urb->transfer_flags = URB_ISO_ASAP; + usb_submit_urb(urb, GFP_ATOMIC); +} + +static void write_completed(struct urb *urb) +{ + struct snd_usb_caiaq_cb_info *info = urb->context; + struct snd_usb_caiaqdev *dev = info->dev; + + if (!dev->output_running) { + dev->output_running = 1; + wake_up(&dev->prepare_wait_queue); + } +} + +static struct urb **alloc_urbs(struct snd_usb_caiaqdev *dev, int dir, int *ret) +{ + int i, frame; + struct urb **urbs; + struct usb_device *usb_dev = dev->chip.dev; + unsigned int pipe; + + pipe = (dir == SNDRV_PCM_STREAM_PLAYBACK) ? + usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) : + usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE); + + urbs = kmalloc(N_URBS * sizeof(*urbs), GFP_KERNEL); + if (!urbs) { + log("unable to kmalloc() urbs, OOM!?\n"); + *ret = -ENOMEM; + return NULL; + } + + for (i = 0; i < N_URBS; i++) { + urbs[i] = usb_alloc_urb(FRAMES_PER_URB, GFP_KERNEL); + if (!urbs[i]) { + log("unable to usb_alloc_urb(), OOM!?\n"); + *ret = -ENOMEM; + return urbs; + } + + urbs[i]->transfer_buffer = + kmalloc(FRAMES_PER_URB * BYTES_PER_FRAME, GFP_KERNEL); + if (!urbs[i]->transfer_buffer) { + log("unable to kmalloc() transfer buffer, OOM!?\n"); + *ret = -ENOMEM; + return urbs; + } + + for (frame = 0; frame < FRAMES_PER_URB; frame++) { + struct usb_iso_packet_descriptor *iso = + &urbs[i]->iso_frame_desc[frame]; + + iso->offset = BYTES_PER_FRAME * frame; + iso->length = BYTES_PER_FRAME; + } + + urbs[i]->dev = usb_dev; + urbs[i]->pipe = pipe; + urbs[i]->transfer_buffer_length = FRAMES_PER_URB + * BYTES_PER_FRAME; + urbs[i]->context = &dev->data_cb_info[i]; + urbs[i]->interval = 1; + urbs[i]->transfer_flags = URB_ISO_ASAP; + urbs[i]->number_of_packets = FRAMES_PER_URB; + urbs[i]->complete = (dir == SNDRV_PCM_STREAM_CAPTURE) ? + read_completed : write_completed; + } + + *ret = 0; + return urbs; +} + +static void free_urbs(struct urb **urbs) +{ + int i; + + if (!urbs) + return; + + for (i = 0; i < N_URBS; i++) { + if (!urbs[i]) + continue; + + usb_kill_urb(urbs[i]); + kfree(urbs[i]->transfer_buffer); + usb_free_urb(urbs[i]); + } + + kfree(urbs); +} + +int __devinit snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev) +{ + int i, ret; + + dev->n_audio_in = max(dev->spec.num_analog_audio_in, + dev->spec.num_digital_audio_in) / + CHANNELS_PER_STREAM; + dev->n_audio_out = max(dev->spec.num_analog_audio_out, + dev->spec.num_digital_audio_out) / + CHANNELS_PER_STREAM; + dev->n_streams = max(dev->n_audio_in, dev->n_audio_out); + + debug("dev->n_audio_in = %d\n", dev->n_audio_in); + debug("dev->n_audio_out = %d\n", dev->n_audio_out); + debug("dev->n_streams = %d\n", dev->n_streams); + + if (dev->n_streams > MAX_STREAMS) { + log("unable to initialize device, too many streams.\n"); + return -EINVAL; + } + + ret = snd_pcm_new(dev->chip.card, dev->product_name, 0, + dev->n_audio_out, dev->n_audio_in, &dev->pcm); + + if (ret < 0) { + log("snd_pcm_new() returned %d\n", ret); + return ret; + } + + dev->pcm->private_data = dev; + strcpy(dev->pcm->name, dev->product_name); + + memset(dev->sub_playback, 0, sizeof(dev->sub_playback)); + memset(dev->sub_capture, 0, sizeof(dev->sub_capture)); + + memcpy(&dev->pcm_info, &snd_usb_caiaq_pcm_hardware, + sizeof(snd_usb_caiaq_pcm_hardware)); + + /* setup samplerates */ + dev->samplerates = dev->pcm_info.rates; + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): + dev->samplerates |= SNDRV_PCM_RATE_88200; + dev->samplerates |= SNDRV_PCM_RATE_192000; + break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): + dev->samplerates |= SNDRV_PCM_RATE_88200; + break; + } + + snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_usb_caiaq_ops); + snd_pcm_set_ops(dev->pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_usb_caiaq_ops); + + snd_pcm_lib_preallocate_pages_for_all(dev->pcm, + SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data(GFP_KERNEL), + MAX_BUFFER_SIZE, MAX_BUFFER_SIZE); + + dev->data_cb_info = + kmalloc(sizeof(struct snd_usb_caiaq_cb_info) * N_URBS, + GFP_KERNEL); + + if (!dev->data_cb_info) + return -ENOMEM; + + for (i = 0; i < N_URBS; i++) { + dev->data_cb_info[i].dev = dev; + dev->data_cb_info[i].index = i; + } + + dev->data_urbs_in = alloc_urbs(dev, SNDRV_PCM_STREAM_CAPTURE, &ret); + if (ret < 0) { + kfree(dev->data_cb_info); + free_urbs(dev->data_urbs_in); + return ret; + } + + dev->data_urbs_out = alloc_urbs(dev, SNDRV_PCM_STREAM_PLAYBACK, &ret); + if (ret < 0) { + kfree(dev->data_cb_info); + free_urbs(dev->data_urbs_in); + free_urbs(dev->data_urbs_out); + return ret; + } + + return 0; +} + +void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev) +{ + debug("snd_usb_caiaq_audio_free (%p)\n", dev); + stream_stop(dev); + free_urbs(dev->data_urbs_in); + free_urbs(dev->data_urbs_out); + kfree(dev->data_cb_info); +} + diff --git a/sound/usb/caiaq/caiaq-audio.h b/sound/usb/caiaq/caiaq-audio.h new file mode 100644 index 0000000..8ab1f8d --- /dev/null +++ b/sound/usb/caiaq/caiaq-audio.h @@ -0,0 +1,7 @@ +#ifndef CAIAQ_AUDIO_H +#define CAIAQ_AUDIO_H + +int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *dev); +void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *dev); + +#endif /* CAIAQ_AUDIO_H */ diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c new file mode 100644 index 0000000..4709347 --- /dev/null +++ b/sound/usb/caiaq/caiaq-device.c @@ -0,0 +1,436 @@ +/* + * caiaq.c: ALSA driver for caiaq/NativeInstruments devices + * + * Copyright (c) 2007 Daniel Mack + * Karsten Wiese + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "caiaq-device.h" +#include "caiaq-audio.h" +#include "caiaq-midi.h" + +#ifdef CONFIG_SND_USB_CAIAQ_INPUT +#include "caiaq-input.h" +#endif + +MODULE_AUTHOR("Daniel Mack "); +MODULE_DESCRIPTION("caiaq USB audio, version 1.1.0"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," + "{Native Instruments, Kore Controller}," + "{Native Instruments, Audio Kontrol 1}" + "{Native Instruments, Audio 8 DJ}}"); + +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ +static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static int snd_card_used[SNDRV_CARDS]; + +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for the caiaq sound device"); +module_param_array(id, charp, NULL, 0444); +MODULE_PARM_DESC(id, "ID string for the caiaq soundcard."); +module_param_array(enable, bool, NULL, 0444); +MODULE_PARM_DESC(enable, "Enable the caiaq soundcard."); + +enum { + SAMPLERATE_44100 = 0, + SAMPLERATE_48000 = 1, + SAMPLERATE_96000 = 2, + SAMPLERATE_192000 = 3, + SAMPLERATE_88200 = 4, + SAMPLERATE_INVALID = 0xff +}; + +enum { + DEPTH_NONE = 0, + DEPTH_16 = 1, + DEPTH_24 = 2, + DEPTH_32 = 3 +}; + +static struct usb_device_id snd_usb_id_table[] = { + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_RIGKONTROL2 + }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_KORECONTROLLER + }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_AK1 + }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = USB_VID_NATIVEINSTRUMENTS, + .idProduct = USB_PID_AUDIO8DJ + }, + { /* terminator */ } +}; + +static void usb_ep1_command_reply_dispatch (struct urb* urb) +{ + int ret; + struct snd_usb_caiaqdev *dev = urb->context; + unsigned char *buf = urb->transfer_buffer; + + if (urb->status || !dev) { + log("received EP1 urb->status = %i\n", urb->status); + return; + } + + switch(buf[0]) { + case EP1_CMD_GET_DEVICE_INFO: + memcpy(&dev->spec, buf+1, sizeof(struct caiaq_device_spec)); + dev->spec.fw_version = le16_to_cpu(dev->spec.fw_version); + debug("device spec (firmware %d): audio: %d in, %d out, " + "MIDI: %d in, %d out, data alignment %d\n", + dev->spec.fw_version, + dev->spec.num_analog_audio_in, + dev->spec.num_analog_audio_out, + dev->spec.num_midi_in, + dev->spec.num_midi_out, + dev->spec.data_alignment); + + dev->spec_received++; + wake_up(&dev->ep1_wait_queue); + break; + case EP1_CMD_AUDIO_PARAMS: + dev->audio_parm_answer = buf[1]; + wake_up(&dev->ep1_wait_queue); + break; + case EP1_CMD_MIDI_READ: + snd_usb_caiaq_midi_handle_input(dev, buf[1], buf + 3, buf[2]); + break; + +#ifdef CONFIG_SND_USB_CAIAQ_INPUT + case EP1_CMD_READ_ERP: + case EP1_CMD_READ_ANALOG: + case EP1_CMD_READ_IO: + snd_usb_caiaq_input_dispatch(dev, buf, urb->actual_length); + break; +#endif + } + + dev->ep1_in_urb.actual_length = 0; + ret = usb_submit_urb(&dev->ep1_in_urb, GFP_ATOMIC); + if (ret < 0) + log("unable to submit urb. OOM!?\n"); +} + +static int send_command (struct snd_usb_caiaqdev *dev, + unsigned char command, + const unsigned char *buffer, + int len) +{ + int actual_len; + struct usb_device *usb_dev = dev->chip.dev; + + if (!usb_dev) + return -EIO; + + if (len > EP1_BUFSIZE - 1) + len = EP1_BUFSIZE - 1; + + if (buffer && len > 0) + memcpy(dev->ep1_out_buf+1, buffer, len); + + dev->ep1_out_buf[0] = command; + return usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, 1), + dev->ep1_out_buf, len+1, &actual_len, 200); +} + +int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, + int rate, int depth, int bpp) +{ + int ret; + char tmp[5]; + + switch (rate) { + case 44100: tmp[0] = SAMPLERATE_44100; break; + case 48000: tmp[0] = SAMPLERATE_48000; break; + case 88200: tmp[0] = SAMPLERATE_88200; break; + case 96000: tmp[0] = SAMPLERATE_96000; break; + case 192000: tmp[0] = SAMPLERATE_192000; break; + default: return -EINVAL; + } + + switch (depth) { + case 16: tmp[1] = DEPTH_16; break; + case 24: tmp[1] = DEPTH_24; break; + default: return -EINVAL; + } + + tmp[2] = bpp & 0xff; + tmp[3] = bpp >> 8; + tmp[4] = 1; /* packets per microframe */ + + debug("setting audio params: %d Hz, %d bits, %d bpp\n", + rate, depth, bpp); + + dev->audio_parm_answer = -1; + ret = send_command(dev, EP1_CMD_AUDIO_PARAMS, tmp, sizeof(tmp)); + + if (ret) + return ret; + + if (!wait_event_timeout(dev->ep1_wait_queue, + dev->audio_parm_answer >= 0, HZ)) + return -EPIPE; + + if (dev->audio_parm_answer != 1) + debug("unable to set the device's audio params\n"); + + return dev->audio_parm_answer == 1 ? 0 : -EINVAL; +} + +int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, + int digital, int analog, int erp) +{ + char tmp[3] = { digital, analog, erp }; + return send_command(dev, EP1_CMD_AUTO_MSG, tmp, sizeof(tmp)); +} + +static void setup_card(struct snd_usb_caiaqdev *dev) +{ + int ret; + char val[3]; + + /* device-specific startup specials */ + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): + /* RigKontrol2 - display centered dash ('-') */ + val[0] = 0x00; + val[1] = 0x00; + val[2] = 0x01; + send_command(dev, EP1_CMD_WRITE_IO, val, 3); + break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): + /* Audio Kontrol 1 - make USB-LED stop blinking */ + val[0] = 0x00; + send_command(dev, EP1_CMD_WRITE_IO, val, 1); + break; + } + + ret = snd_usb_caiaq_audio_init(dev); + if (ret < 0) + log("Unable to set up audio system (ret=%d)\n", ret); + + ret = snd_usb_caiaq_midi_init(dev); + if (ret < 0) + log("Unable to set up MIDI system (ret=%d)\n", ret); + +#ifdef CONFIG_SND_USB_CAIAQ_INPUT + ret = snd_usb_caiaq_input_init(dev); + if (ret < 0) + log("Unable to set up input system (ret=%d)\n", ret); +#endif + + /* finally, register the card and all its sub-instances */ + ret = snd_card_register(dev->chip.card); + if (ret < 0) { + log("snd_card_register() returned %d\n", ret); + snd_card_free(dev->chip.card); + } +} + +static struct snd_card* create_card(struct usb_device* usb_dev) +{ + int devnum; + struct snd_card *card; + struct snd_usb_caiaqdev *dev; + + for (devnum = 0; devnum < SNDRV_CARDS; devnum++) + if (enable[devnum] && !snd_card_used[devnum]) + break; + + if (devnum >= SNDRV_CARDS) + return NULL; + + card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, + sizeof(struct snd_usb_caiaqdev)); + if (!card) + return NULL; + + dev = caiaqdev(card); + dev->chip.dev = usb_dev; + dev->chip.card = card; + dev->chip.usb_id = USB_ID(usb_dev->descriptor.idVendor, + usb_dev->descriptor.idProduct); + spin_lock_init(&dev->spinlock); + snd_card_set_dev(card, &usb_dev->dev); + + return card; +} + +static int init_card(struct snd_usb_caiaqdev *dev) +{ + char *c; + struct usb_device *usb_dev = dev->chip.dev; + struct snd_card *card = dev->chip.card; + int err, len; + + if (usb_set_interface(usb_dev, 0, 1) != 0) { + log("can't set alt interface.\n"); + return -EIO; + } + + usb_init_urb(&dev->ep1_in_urb); + usb_init_urb(&dev->midi_out_urb); + + usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev, + usb_rcvbulkpipe(usb_dev, 0x1), + dev->ep1_in_buf, EP1_BUFSIZE, + usb_ep1_command_reply_dispatch, dev); + + usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev, + usb_sndbulkpipe(usb_dev, 0x1), + dev->midi_out_buf, EP1_BUFSIZE, + snd_usb_caiaq_midi_output_done, dev); + + init_waitqueue_head(&dev->ep1_wait_queue); + init_waitqueue_head(&dev->prepare_wait_queue); + + if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0) + return -EIO; + + err = send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0); + if (err) + return err; + + if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ)) + return -ENODEV; + + usb_string(usb_dev, usb_dev->descriptor.iManufacturer, + dev->vendor_name, CAIAQ_USB_STR_LEN); + + usb_string(usb_dev, usb_dev->descriptor.iProduct, + dev->product_name, CAIAQ_USB_STR_LEN); + + usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, + dev->serial, CAIAQ_USB_STR_LEN); + + /* terminate serial string at first white space occurence */ + c = strchr(dev->serial, ' '); + if (c) + *c = '\0'; + + strcpy(card->driver, MODNAME); + strcpy(card->shortname, dev->product_name); + + len = snprintf(card->longname, sizeof(card->longname), + "%s %s (serial %s, ", + dev->vendor_name, dev->product_name, dev->serial); + + if (len < sizeof(card->longname) - 2) + len += usb_make_path(usb_dev, card->longname + len, + sizeof(card->longname) - len); + + card->longname[len++] = ')'; + card->longname[len] = '\0'; + setup_card(dev); + return 0; +} + +static int snd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + int ret; + struct snd_card *card; + struct usb_device *device = interface_to_usbdev(intf); + + card = create_card(device); + + if (!card) + return -ENOMEM; + + dev_set_drvdata(&intf->dev, card); + ret = init_card(caiaqdev(card)); + if (ret < 0) { + log("unable to init card! (ret=%d)\n", ret); + snd_card_free(card); + return ret; + } + + return 0; +} + +static void snd_disconnect(struct usb_interface *intf) +{ + struct snd_usb_caiaqdev *dev; + struct snd_card *card = dev_get_drvdata(&intf->dev); + + debug("snd_disconnect(%p)\n", intf); + + if (!card) + return; + + dev = caiaqdev(card); + snd_card_disconnect(card); + +#ifdef CONFIG_SND_USB_CAIAQ_INPUT + snd_usb_caiaq_input_free(dev); +#endif + snd_usb_caiaq_audio_free(dev); + + usb_kill_urb(&dev->ep1_in_urb); + usb_kill_urb(&dev->midi_out_urb); + + snd_card_free(card); + usb_reset_device(interface_to_usbdev(intf)); +} + + +MODULE_DEVICE_TABLE(usb, snd_usb_id_table); +static struct usb_driver snd_usb_driver = { + .name = MODNAME, + .probe = snd_probe, + .disconnect = snd_disconnect, + .id_table = snd_usb_id_table, +}; + +static int __init snd_module_init(void) +{ + return usb_register(&snd_usb_driver); +} + +static void __exit snd_module_exit(void) +{ + usb_deregister(&snd_usb_driver); +} + +module_init(snd_module_init) +module_exit(snd_module_exit) + diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h new file mode 100644 index 0000000..088d5ec --- /dev/null +++ b/sound/usb/caiaq/caiaq-device.h @@ -0,0 +1,116 @@ +#ifndef CAIAQ_DEVICE_H +#define CAIAQ_DEVICE_H + +#include "../usbaudio.h" + +#define USB_VID_NATIVEINSTRUMENTS 0x17cc + +#define USB_PID_RIGKONTROL2 0x1969 +#define USB_PID_KORECONTROLLER 0x4711 +#define USB_PID_AK1 0x0815 +#define USB_PID_AUDIO8DJ 0x1978 + +#define EP1_BUFSIZE 64 +#define CAIAQ_USB_STR_LEN 0xff +#define MAX_STREAMS 32 + +//#define SND_USB_CAIAQ_DEBUG + +#define MODNAME "snd-usb-caiaq" +#define log(x...) snd_printk(KERN_WARNING MODNAME" log: " x) + +#ifdef SND_USB_CAIAQ_DEBUG +#define debug(x...) snd_printk(KERN_WARNING MODNAME " debug: " x) +#else +#define debug(x...) do { } while(0) +#endif + +#define EP1_CMD_GET_DEVICE_INFO 0x1 +#define EP1_CMD_READ_ERP 0x2 +#define EP1_CMD_READ_ANALOG 0x3 +#define EP1_CMD_READ_IO 0x4 +#define EP1_CMD_WRITE_IO 0x5 +#define EP1_CMD_MIDI_READ 0x6 +#define EP1_CMD_MIDI_WRITE 0x7 +#define EP1_CMD_AUDIO_PARAMS 0x9 +#define EP1_CMD_AUTO_MSG 0xb + +struct caiaq_device_spec { + unsigned short fw_version; + unsigned char hw_subtype; + unsigned char num_erp; + unsigned char num_analog_in; + unsigned char num_digital_in; + unsigned char num_digital_out; + unsigned char num_analog_audio_out; + unsigned char num_analog_audio_in; + unsigned char num_digital_audio_out; + unsigned char num_digital_audio_in; + unsigned char num_midi_out; + unsigned char num_midi_in; + unsigned char data_alignment; +} __attribute__ ((packed)); + +struct snd_usb_caiaq_cb_info; + +struct snd_usb_caiaqdev { + struct snd_usb_audio chip; + + struct urb ep1_in_urb; + struct urb midi_out_urb; + struct urb **data_urbs_in; + struct urb **data_urbs_out; + struct snd_usb_caiaq_cb_info *data_cb_info; + + unsigned char ep1_in_buf[EP1_BUFSIZE]; + unsigned char ep1_out_buf[EP1_BUFSIZE]; + unsigned char midi_out_buf[EP1_BUFSIZE]; + + struct caiaq_device_spec spec; + spinlock_t spinlock; + wait_queue_head_t ep1_wait_queue; + wait_queue_head_t prepare_wait_queue; + int spec_received, audio_parm_answer; + + char vendor_name[CAIAQ_USB_STR_LEN]; + char product_name[CAIAQ_USB_STR_LEN]; + char serial[CAIAQ_USB_STR_LEN]; + + int n_streams, n_audio_in, n_audio_out; + int streaming, first_packet, output_running; + int audio_in_buf_pos[MAX_STREAMS]; + int audio_out_buf_pos[MAX_STREAMS]; + int period_in_count[MAX_STREAMS]; + int period_out_count[MAX_STREAMS]; + int input_panic, output_panic; + char *audio_in_buf, *audio_out_buf; + unsigned int samplerates; + + struct snd_pcm_substream *sub_playback[MAX_STREAMS]; + struct snd_pcm_substream *sub_capture[MAX_STREAMS]; + + /* Linux input */ +#ifdef CONFIG_SND_USB_CAIAQ_INPUT + struct input_dev *input_dev; +#endif + + /* ALSA */ + struct snd_pcm *pcm; + struct snd_pcm_hardware pcm_info; + struct snd_rawmidi *rmidi; + struct snd_rawmidi_substream *midi_receive_substream; + struct snd_rawmidi_substream *midi_out_substream; +}; + +struct snd_usb_caiaq_cb_info { + struct snd_usb_caiaqdev *dev; + int index; +}; + +#define caiaqdev(c) ((struct snd_usb_caiaqdev*)(c)->private_data) + +int snd_usb_caiaq_set_audio_params (struct snd_usb_caiaqdev *dev, int rate, int depth, int bbp); +int snd_usb_caiaq_set_auto_msg (struct snd_usb_caiaqdev *dev, int digital, int analog, int erp); + + +#endif /* CAIAQ_DEVICE_H */ diff --git a/sound/usb/caiaq/caiaq-input.c b/sound/usb/caiaq/caiaq-input.c new file mode 100644 index 0000000..3acd12d --- /dev/null +++ b/sound/usb/caiaq/caiaq-input.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2006,2007 Daniel Mack, Tim Ruetz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "caiaq-device.h" +#include "caiaq-input.h" + +#ifdef CONFIG_SND_USB_CAIAQ_INPUT + +static unsigned char keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; +static unsigned char keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, + KEY_5, KEY_6, KEY_7 }; + +#define DEG90 (range/2) +#define DEG180 (range) +#define DEG270 (DEG90 + DEG180) +#define DEG360 (DEG180 * 2) +#define HIGH_PEAK (268) +#define LOW_PEAK (-7) + +/* some of these devices have endless rotation potentiometers + * built in which use two tapers, 90 degrees phase shifted. + * this algorithm decodes them to one single value, ranging + * from 0 to 999 */ +static unsigned int decode_erp(unsigned char a, unsigned char b) +{ + int weight_a, weight_b; + int pos_a, pos_b; + int ret; + int range = HIGH_PEAK - LOW_PEAK; + int mid_value = (HIGH_PEAK + LOW_PEAK) / 2; + + weight_b = abs(mid_value-a) - (range/2 - 100)/2; + + if (weight_b < 0) + weight_b = 0; + + if (weight_b > 100) + weight_b = 100; + + weight_a = 100 - weight_b; + + if (a < mid_value) { + /* 0..90 and 270..360 degrees */ + pos_b = b - LOW_PEAK + DEG270; + if (pos_b >= DEG360) + pos_b -= DEG360; + } else + /* 90..270 degrees */ + pos_b = HIGH_PEAK - b + DEG90; + + + if (b > mid_value) + /* 0..180 degrees */ + pos_a = a - LOW_PEAK; + else + /* 180..360 degrees */ + pos_a = HIGH_PEAK - a + DEG180; + + /* interpolate both slider values, depending on weight factors */ + /* 0..99 x DEG360 */ + ret = pos_a * weight_a + pos_b * weight_b; + + /* normalize to 0..999 */ + ret *= 10; + ret /= DEG360; + + if (ret < 0) + ret += 1000; + + if (ret >= 1000) + ret -= 1000; + + return ret; +} + +#undef DEG90 +#undef DEG180 +#undef DEG270 +#undef DEG360 +#undef HIGH_PEAK +#undef LOW_PEAK + + +static void snd_caiaq_input_read_analog(struct snd_usb_caiaqdev *dev, + const char *buf, unsigned int len) +{ + switch(dev->input_dev->id.product) { + case USB_PID_RIGKONTROL2: + input_report_abs(dev->input_dev, ABS_X, (buf[4] << 8) |buf[5]); + input_report_abs(dev->input_dev, ABS_Y, (buf[0] << 8) |buf[1]); + input_report_abs(dev->input_dev, ABS_Z, (buf[2] << 8) |buf[3]); + input_sync(dev->input_dev); + break; + } +} + +static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, + const char *buf, unsigned int len) +{ + int i; + + switch(dev->input_dev->id.product) { + case USB_PID_AK1: + i = decode_erp(buf[0], buf[1]); + input_report_abs(dev->input_dev, ABS_X, i); + input_sync(dev->input_dev); + break; + } +} + +static void snd_caiaq_input_read_io(struct snd_usb_caiaqdev *dev, + char *buf, unsigned int len) +{ + int i; + unsigned char *keycode = dev->input_dev->keycode; + + if (!keycode) + return; + + if (dev->input_dev->id.product == USB_PID_RIGKONTROL2) + for (i=0; iinput_dev->keycodemax) && (i < len); i++) + input_report_key(dev->input_dev, keycode[i], + buf[i/8] & (1 << (i%8))); + + input_sync(dev->input_dev); +} + +void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, + char *buf, + unsigned int len) +{ + if (!dev->input_dev || (len < 1)) + return; + + switch (buf[0]) { + case EP1_CMD_READ_ANALOG: + snd_caiaq_input_read_analog(dev, buf+1, len-1); + break; + case EP1_CMD_READ_ERP: + snd_caiaq_input_read_erp(dev, buf+1, len-1); + break; + case EP1_CMD_READ_IO: + snd_caiaq_input_read_io(dev, buf+1, len-1); + break; + } +} + +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; + + input = input_allocate_device(); + if (!input) + return -ENOMEM; + + input->name = dev->product_name; + input->id.bustype = BUS_USB; + input->id.vendor = usb_dev->descriptor.idVendor; + input->id.product = usb_dev->descriptor.idProduct; + input->id.version = usb_dev->descriptor.bcdDevice; + + switch (dev->chip.usb_id) { + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): + input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z); + input->keycode = keycode_rk2; + input->keycodesize = sizeof(char); + input->keycodemax = ARRAY_SIZE(keycode_rk2); + for (i=0; ikeybit); + + input_set_abs_params(input, ABS_X, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10); + input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10); + snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0); + break; + case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): + input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input->absbit[0] = BIT(ABS_X); + input->keycode = keycode_ak1; + input->keycodesize = sizeof(char); + input->keycodemax = ARRAY_SIZE(keycode_ak1); + for (i=0; ikeybit); + + input_set_abs_params(input, ABS_X, 0, 999, 0, 10); + snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5); + break; + default: + /* no input methods supported on this device */ + input_free_device(input); + return 0; + } + + ret = input_register_device(input); + if (ret < 0) { + input_free_device(input); + return ret; + } + + dev->input_dev = input; + return 0; +} + +void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) +{ + if (!dev || !dev->input_dev) + return; + + input_unregister_device(dev->input_dev); + input_free_device(dev->input_dev); + dev->input_dev = NULL; +} + +#endif /* CONFIG_SND_USB_CAIAQ_INPUT */ + diff --git a/sound/usb/caiaq/caiaq-input.h b/sound/usb/caiaq/caiaq-input.h new file mode 100644 index 0000000..ced5355 --- /dev/null +++ b/sound/usb/caiaq/caiaq-input.h @@ -0,0 +1,8 @@ +#ifndef CAIAQ_INPUT_H +#define CAIAQ_INPUT_H + +void snd_usb_caiaq_input_dispatch(struct snd_usb_caiaqdev *dev, char *buf, unsigned int len); +int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev); +void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev); + +#endif diff --git a/sound/usb/caiaq/caiaq-midi.c b/sound/usb/caiaq/caiaq-midi.c new file mode 100644 index 0000000..793ca20 --- /dev/null +++ b/sound/usb/caiaq/caiaq-midi.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2006,2007 Daniel Mack + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "caiaq-device.h" +#include "caiaq-midi.h" + + +static int snd_usb_caiaq_midi_input_open(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +static int snd_usb_caiaq_midi_input_close(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +static void snd_usb_caiaq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) +{ + struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; + + if (!dev) + return; + + dev->midi_receive_substream = up ? substream : NULL; +} + + +static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev, + struct snd_rawmidi_substream *substream) +{ + int len, ret; + + dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE; + dev->midi_out_buf[1] = 0; /* port */ + len = snd_rawmidi_transmit_peek(substream, dev->midi_out_buf+3, EP1_BUFSIZE-3); + + if (len <= 0) + return; + + dev->midi_out_buf[2] = len; + dev->midi_out_urb.transfer_buffer_length = len+3; + + ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC); + if (ret < 0) + log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed, %d\n", + substream, ret); +} + +static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) +{ + struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; + + if (dev->midi_out_substream != NULL) + return; + + if (!up) { + dev->midi_out_substream = NULL; + return; + } + + dev->midi_out_substream = substream; + snd_usb_caiaq_midi_send(dev, substream); +} + + +static struct snd_rawmidi_ops snd_usb_caiaq_midi_output = +{ + .open = snd_usb_caiaq_midi_output_open, + .close = snd_usb_caiaq_midi_output_close, + .trigger = snd_usb_caiaq_midi_output_trigger, +}; + +static struct snd_rawmidi_ops snd_usb_caiaq_midi_input = +{ + .open = snd_usb_caiaq_midi_input_open, + .close = snd_usb_caiaq_midi_input_close, + .trigger = snd_usb_caiaq_midi_input_trigger, +}; + +void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, + int port, const char *buf, int len) +{ + if (!dev->midi_receive_substream) + return; + + snd_rawmidi_receive(dev->midi_receive_substream, buf, len); +} + +int __devinit snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device) +{ + int ret; + struct snd_rawmidi *rmidi; + + ret = snd_rawmidi_new(device->chip.card, device->product_name, 0, + device->spec.num_midi_out, + device->spec.num_midi_in, + &rmidi); + + if (ret < 0) + return ret; + + strcpy(rmidi->name, device->product_name); + + rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX; + rmidi->private_data = device; + + if (device->spec.num_midi_out > 0) { + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, + &snd_usb_caiaq_midi_output); + } + + if (device->spec.num_midi_in > 0) { + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, + &snd_usb_caiaq_midi_input); + } + + device->rmidi = rmidi; + + return 0; +} + +void snd_usb_caiaq_midi_output_done(struct urb* urb) +{ + struct snd_usb_caiaqdev *dev = urb->context; + char *buf = urb->transfer_buffer; + + if (urb->status != 0) + return; + + if (!dev->midi_out_substream) + return; + + snd_rawmidi_transmit_ack(dev->midi_out_substream, buf[2]); + dev->midi_out_substream = NULL; + snd_usb_caiaq_midi_send(dev, dev->midi_out_substream); +} + diff --git a/sound/usb/caiaq/caiaq-midi.h b/sound/usb/caiaq/caiaq-midi.h new file mode 100644 index 0000000..9d16db0 --- /dev/null +++ b/sound/usb/caiaq/caiaq-midi.h @@ -0,0 +1,8 @@ +#ifndef CAIAQ_MIDI_H +#define CAIAQ_MIDI_H + +int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *dev); +void snd_usb_caiaq_midi_handle_input(struct snd_usb_caiaqdev *dev, int port, const char *buf, int len); +void snd_usb_caiaq_midi_output_done(struct urb* urb); + +#endif /* CAIAQ_MIDI_H */ -- cgit v0.10.2 From 023ff3eee6255390384e050d9daab1490c88edf8 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 27 Mar 2007 11:50:19 +0200 Subject: [ALSA] sound: strlcpy is smart enough strlcpy already accounts for the trailing zero in its length computation, so there is no need to substract one to the buffer size. Signed-off-by: Jean Delvare Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/snd-aoa-codec-onyx.c index e91f9f6..ded5167 100644 --- a/sound/aoa/codecs/snd-aoa-codec-onyx.c +++ b/sound/aoa/codecs/snd-aoa-codec-onyx.c @@ -1018,7 +1018,7 @@ static int onyx_create(struct i2c_adapter *adapter, onyx->i2c.driver = &onyx_driver; onyx->i2c.adapter = adapter; onyx->i2c.addr = addr & 0x7f; - strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE-1); + strlcpy(onyx->i2c.name, "onyx audio codec", I2C_NAME_SIZE); if (i2c_attach_client(&onyx->i2c)) { printk(KERN_ERR PFX "failed to attach to i2c\n"); @@ -1033,7 +1033,7 @@ static int onyx_create(struct i2c_adapter *adapter, goto fail; } - strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN-1); + strlcpy(onyx->codec.name, "onyx", MAX_CODEC_NAME_LEN); onyx->codec.owner = THIS_MODULE; onyx->codec.init = onyx_init_codec; onyx->codec.exit = onyx_exit_codec; diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c index 041fe52..2f771f5 100644 --- a/sound/aoa/codecs/snd-aoa-codec-tas.c +++ b/sound/aoa/codecs/snd-aoa-codec-tas.c @@ -899,14 +899,14 @@ static int tas_create(struct i2c_adapter *adapter, tas->i2c.addr = addr; /* seems that half is a saner default */ tas->drc_range = TAS3004_DRC_MAX / 2; - strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1); + strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE); if (i2c_attach_client(&tas->i2c)) { printk(KERN_ERR PFX "failed to attach to i2c\n"); goto fail; } - strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN-1); + strlcpy(tas->codec.name, "tas", MAX_CODEC_NAME_LEN); tas->codec.owner = THIS_MODULE; tas->codec.init = tas_init_codec; tas->codec.exit = tas_exit_codec; -- cgit v0.10.2 From 6d5fc07aee79327eba5e50a3afa4c1f11b4291d6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 27 Mar 2007 15:54:27 +0200 Subject: [ALSA] ak4114 - Fix a typo in DIF2 bit definition Fixed a typo in AK4114_DIF2 bit definition. This may fix some problems for Audiophile 192 and Juli boards. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h index c149d3b25..54a5a42 100644 --- a/include/sound/ak4114.h +++ b/include/sound/ak4114.h @@ -73,7 +73,7 @@ /* AK4114_REQ_FORMAT bits */ #define AK4114_MONO (1<<7) /* Double Sampling Frequency Mode: 0 = stereo, 1 = mono */ -#define AK4114_DIF2 (1<<5) /* Audio Data Control */ +#define AK4114_DIF2 (1<<6) /* Audio Data Control */ #define AK4114_DIF1 (1<<5) /* Audio Data Control */ #define AK4114_DIF0 (1<<4) /* Audio Data Control */ #define AK4114_DIF_16R (0) /* STDO: 16-bit, right justified */ -- cgit v0.10.2 From e3f9678c36dc81fde5dc86848d6d6077659ecaf0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 28 Mar 2007 13:42:25 +0200 Subject: [ALSA] snd-aoa-i2sbus: use MODULE_DEVICE_TABLE instead of plain MODULE_ALIAS This patch changes snd-aoa-i2sbus to use MODULE_DEVICE_TABLE instead of a hardcoded MODULE_ALIAS. Thanks to Sylvain Munaut for pointing this out. Signed-off-by: Johannes Berg Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/i2sbus-core.c index 0fccdbf..efb9441 100644 --- a/sound/aoa/soundbus/i2sbus/i2sbus-core.c +++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c @@ -23,9 +23,6 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Johannes Berg "); MODULE_DESCRIPTION("Apple Soundbus: I2S support"); -/* for auto-loading, declare that we handle this weird - * string that macio puts into the relevant device */ -MODULE_ALIAS("of:Ni2sTi2sC"); static int force; module_param(force, int, 0444); @@ -37,6 +34,8 @@ static struct of_device_id i2sbus_match[] = { { } }; +MODULE_DEVICE_TABLE(of, i2sbus_match); + static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev, struct dbdma_command_mem *r, int numcmds) -- cgit v0.10.2 From d3091fad4a4902185c3ce0b77a847ecafcb3f006 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 28 Mar 2007 15:11:53 +0200 Subject: [ALSA] hda-codec - Fix missing array terminators Added missing array terminators in patch_conexant.c. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index c7fb0b8..efb95dc 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -632,11 +632,13 @@ static struct hda_verb cxt5045_init_verbs[] = { static struct hda_verb cxt5045_hp_sense_init_verbs[] = { /* pin sensing on HP jack */ {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, + { } /* end */ }; static struct hda_verb cxt5045_mic_sense_init_verbs[] = { /* pin sensing on HP jack */ {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, + { } /* end */ }; #ifdef CONFIG_SND_DEBUG -- cgit v0.10.2 From b942cf815b5775288550f99f3790e29815bb70cb Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Wed, 28 Mar 2007 15:23:53 +0200 Subject: [ALSA] es1968 - Fix stuttering capture Looks like the buffer size for the stereo capture has to be a power of two. Now added a constraint to buffer bytes. Also removed unnecessary #if 0 lines. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index dc84c18..2faf009 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -1554,10 +1554,7 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream) runtime->hw = snd_es1968_playback; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip); -#if 0 - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - 1024); -#endif + spin_lock_irq(&chip->substream_lock); list_add(&es->list, &chip->substream_list); spin_unlock_irq(&chip->substream_lock); @@ -1613,10 +1610,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream) runtime->hw = snd_es1968_capture; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */ -#if 0 - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - 1024); -#endif + snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); + spin_lock_irq(&chip->substream_lock); list_add(&es->list, &chip->substream_list); spin_unlock_irq(&chip->substream_lock); -- cgit v0.10.2 From b07a14a549589e23be40f6b344df9512ba462e3f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 28 Mar 2007 17:19:29 +0200 Subject: [ALSA] pcxhr - Minor optimization in trigger callback Minor optimization in trigger start callback. This fixes a nasty compile warning, too. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index e1bdeed..f7f6a687 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -639,19 +639,21 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) { struct pcxhr_stream *stream; struct snd_pcm_substream *s; - int i; switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_printdd("SNDRV_PCM_TRIGGER_START\n"); - i = 0; - snd_pcm_group_for_each_entry(s, subs) { - stream = s->runtime->private_data; - stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN; - snd_pcm_trigger_done(s, subs); - i++; - } - if (i==1) { + if (snd_pcm_stream_linked(subs)) { + struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); + snd_pcm_group_for_each_entry(s, subs) { + stream = s->runtime->private_data; + stream->status = + PCXHR_STREAM_STATUS_SCHEDULE_RUN; + snd_pcm_trigger_done(s, subs); + } + tasklet_hi_schedule(&chip->mgr->trigger_taskq); + } else { + stream = subs->runtime->private_data; snd_printdd("Only one Substream %c %d\n", stream->pipe->is_capture ? 'C' : 'P', stream->pipe->first_audio); @@ -663,9 +665,6 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) if (pcxhr_set_stream_state(stream)) return -EINVAL; stream->status = PCXHR_STREAM_STATUS_RUNNING; - } else { - struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); - tasklet_hi_schedule(&chip->mgr->trigger_taskq); } break; case SNDRV_PCM_TRIGGER_STOP: -- cgit v0.10.2 From c052f046240b094b2ec12e0004e47756302e2b55 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 29 Mar 2007 12:34:15 +0200 Subject: [ALSA] ice1724 - Fix AP192 4wire mode access ap192_4wire_start() in ice1712/revo.c returns unsigned char whereas it should return unsigned int. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 41f4026..690ceb3 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -405,7 +405,7 @@ static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, return data; } -static unsigned char ap192_4wire_start(struct snd_ice1712 *ice) +static unsigned int ap192_4wire_start(struct snd_ice1712 *ice) { unsigned int tmp; -- cgit v0.10.2 From a971c3d42524afc5619fa271d59d29be3c1661e3 Mon Sep 17 00:00:00 2001 From: Karsten Wiese Date: Thu, 29 Mar 2007 17:02:45 +0200 Subject: [ALSA] snd-usb-caiaq: Make playback work some typo fixes. Signed-off-by: Karsten Wiese Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/usb/caiaq/caiaq-audio.c b/sound/usb/caiaq/caiaq-audio.c index e80c8db..0414d76 100644 --- a/sound/usb/caiaq/caiaq-audio.c +++ b/sound/usb/caiaq/caiaq-audio.c @@ -388,8 +388,8 @@ static void read_in_urb_mode2(struct snd_usb_caiaqdev *dev, struct snd_pcm_runtime *rt = sub->runtime; char *audio_buf = rt->dma_area; int sz = frames_to_bytes(rt, rt->buffer_size); - audio_buf[dev->audio_in_buf_pos[stream]++] - = usb_buf[i]; + audio_buf[dev->audio_in_buf_pos[stream]++] = + usb_buf[i]; dev->period_in_count[stream]++; if (dev->audio_in_buf_pos[stream] == sz) dev->audio_in_buf_pos[stream] = 0; @@ -436,19 +436,21 @@ static void fill_out_urb(struct snd_usb_caiaqdev *dev, spin_lock(&dev->spinlock); for (i = 0; i < iso->length;) { - for (stream = 0; stream < dev->n_streams; stream++) { + for (stream = 0; stream < dev->n_streams; stream++, i++) { sub = dev->sub_playback[stream]; if (sub) { struct snd_pcm_runtime *rt = sub->runtime; char *audio_buf = rt->dma_area; int sz = frames_to_bytes(rt, rt->buffer_size); - usb_buf[i++] - = audio_buf[dev->audio_out_buf_pos[stream]++]; + usb_buf[i] = + audio_buf[dev->audio_out_buf_pos[stream]]; + dev->period_out_count[stream]++; dev->audio_out_buf_pos[stream]++; if (dev->audio_out_buf_pos[stream] == sz) dev->audio_out_buf_pos[stream] = 0; } else - usb_buf[i++] = 0; + usb_buf[i] = 0; + } /* fill in the check bytes */ if (dev->spec.data_alignment == 2 && @@ -456,7 +458,6 @@ static void fill_out_urb(struct snd_usb_caiaqdev *dev, (dev->n_streams * CHANNELS_PER_STREAM)) for (stream = 0; stream < dev->n_streams; stream++, i++) usb_buf[i] = MAKE_CHECKBYTE(dev, stream, i); - } } spin_unlock(&dev->spinlock); -- cgit v0.10.2 From 51354ae3b8fdbeaf96e23ddf787432a38eba31f5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 30 Mar 2007 15:38:39 +0200 Subject: [ALSA] ak4114 - Fix possible Oops with callbacks ak4114 code may trigger Oops when the parameters are changed without call of snd_ak4114_build(). Now it checks the existence of kctl element, and the workq is triggered after building the necessary kcontrols. Also, did some code clean up. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c index adbfd58..8f7c42c 100644 --- a/sound/i2c/other/ak4114.c +++ b/sound/i2c/other/ak4114.c @@ -36,6 +36,7 @@ MODULE_LICENSE("GPL"); #define AK4114_ADDR 0x00 /* fixed address */ static void ak4114_stats(struct work_struct *work); +static void ak4114_init_regs(struct ak4114 *chip); static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val) { @@ -105,7 +106,7 @@ int snd_ak4114_create(struct snd_card *card, for (reg = 0; reg < 5; reg++) chip->txcsb[reg] = txcsb[reg]; - snd_ak4114_reinit(chip); + ak4114_init_regs(chip); chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT); chip->rcs1 = reg_read(chip, AK4114_REG_RCS1); @@ -131,13 +132,10 @@ void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char (chip->txcsb[reg-AK4114_REG_TXCSB0] & ~mask) | val); } -void snd_ak4114_reinit(struct ak4114 *chip) +static void ak4114_init_regs(struct ak4114 *chip) { unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg; - chip->init = 1; - mb(); - flush_scheduled_work(); /* bring the chip to reset state and powerdown state */ reg_write(chip, AK4114_REG_PWRDN, old & ~(AK4114_RST|AK4114_PWN)); udelay(200); @@ -150,9 +148,18 @@ void snd_ak4114_reinit(struct ak4114 *chip) reg_write(chip, reg + AK4114_REG_TXCSB0, chip->txcsb[reg]); /* release powerdown, everything is initialized now */ reg_write(chip, AK4114_REG_PWRDN, old | AK4114_RST | AK4114_PWN); +} + +void snd_ak4114_reinit(struct ak4114 *chip) +{ + chip->init = 1; + mb(); + flush_scheduled_work(); + ak4114_init_regs(chip); /* bring up statistics / event queing */ chip->init = 0; - schedule_delayed_work(&chip->work, HZ / 10); + if (chip->kctls[0]) + schedule_delayed_work(&chip->work, HZ / 10); } static unsigned int external_rate(unsigned char rcs1) @@ -472,9 +479,55 @@ int snd_ak4114_build(struct ak4114 *ak4114, return err; ak4114->kctls[idx] = kctl; } + /* trigger workq */ + schedule_delayed_work(&ak4114->work, HZ / 10); return 0; } +/* notify kcontrols if any parameters are changed */ +static void ak4114_notify(struct ak4114 *ak4114, + unsigned char rcs0, unsigned char rcs1, + unsigned char c0, unsigned char c1) +{ + if (!ak4114->kctls[0]) + return; + + if (rcs0 & AK4114_PAR) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[0]->id); + if (rcs0 & AK4114_V) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[1]->id); + if (rcs1 & AK4114_CCRC) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[2]->id); + if (rcs1 & AK4114_QCRC) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[3]->id); + + /* rate change */ + if (c1 & 0xf0) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[4]->id); + + if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT)) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[9]->id); + if (c0 & AK4114_QINT) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[10]->id); + + if (c0 & AK4114_AUDION) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[11]->id); + if (c0 & AK4114_AUTO) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[12]->id); + if (c0 & AK4114_DTSCD) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[13]->id); +} + int snd_ak4114_external_rate(struct ak4114 *ak4114) { unsigned char rcs1; @@ -511,31 +564,7 @@ int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags) ak4114->rcs1 = rcs1; spin_unlock_irqrestore(&ak4114->lock, _flags); - if (rcs0 & AK4114_PAR) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[0]->id); - if (rcs0 & AK4114_V) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[1]->id); - if (rcs1 & AK4114_CCRC) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[2]->id); - if (rcs1 & AK4114_QCRC) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[3]->id); - - /* rate change */ - if (c1 & 0xf0) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[4]->id); - - if ((c0 & AK4114_PEM) | (c0 & AK4114_CINT)) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[9]->id); - if (c0 & AK4114_QINT) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[10]->id); - - if (c0 & AK4114_AUDION) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[11]->id); - if (c0 & AK4114_AUTO) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[12]->id); - if (c0 & AK4114_DTSCD) - snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[13]->id); - + ak4114_notify(ak4114, rcs0, rcs1, c0, c1); if (ak4114->change_callback && (c0 | c1) != 0) ak4114->change_callback(ak4114, c0, c1); @@ -559,8 +588,8 @@ static void ak4114_stats(struct work_struct *work) struct ak4114 *chip = container_of(work, struct ak4114, work.work); if (chip->init) - return; - snd_ak4114_check_rate_and_errors(chip, 0); + snd_ak4114_check_rate_and_errors(chip, 0); + schedule_delayed_work(&chip->work, HZ / 10); } diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 6d3c633..dd0da95 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -160,13 +160,6 @@ static int __devinit juli_init(struct snd_ice1712 *ice) int err; struct snd_akm4xxx *ak; -#if 0 - for (err = 0; err < 0x20; err++) - juli_ak4114_read(ice, err); - juli_ak4114_write(ice, 0, 0x0f); - juli_ak4114_read(ice, 0); - juli_ak4114_read(ice, 1); -#endif err = snd_ak4114_create(ice->card, juli_ak4114_read, juli_ak4114_write, -- cgit v0.10.2 From f9ab2b1c3ab5345f9003bf7ebc1eaa0f9b8cf99e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 3 Apr 2007 13:20:49 +0200 Subject: [ALSA] ali5451 - Code clean up, irq handler fix - Clean up ali5451.c, following the standard coding style, unneeded codes reduced, and removal of redundant variable initializations. Hungarian notation isn't fixed yet ;) - Fix irq handler to return IRQ_NONE properly for shared irqs. Also check the hardware availability in irq handler to avoid possible initialization races at loading the driver. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index cd2fe37..e1ed595 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -69,10 +69,10 @@ module_param(enable, bool, 0444); * Debug part definitions */ -//#define ALI_DEBUG +/* #define ALI_DEBUG */ #ifdef ALI_DEBUG -#define snd_ali_printk(format, args...) printk(format, ##args); +#define snd_ali_printk(format, args...) printk(KERN_DEBUG format, ##args); #else #define snd_ali_printk(format, args...) #endif @@ -105,10 +105,10 @@ module_param(enable, bool, 0444); * Direct Registers */ -#define ALI_LEGACY_DMAR0 0x00 // ADR0 -#define ALI_LEGACY_DMAR4 0x04 // CNT0 -#define ALI_LEGACY_DMAR11 0x0b // MOD -#define ALI_LEGACY_DMAR15 0x0f // MMR +#define ALI_LEGACY_DMAR0 0x00 /* ADR0 */ +#define ALI_LEGACY_DMAR4 0x04 /* CNT0 */ +#define ALI_LEGACY_DMAR11 0x0b /* MOD */ +#define ALI_LEGACY_DMAR15 0x0f /* MMR */ #define ALI_MPUR0 0x20 #define ALI_MPUR1 0x21 #define ALI_MPUR2 0x22 @@ -175,7 +175,7 @@ struct snd_ali; struct snd_ali_voice; struct snd_ali_channel_control { - // register data + /* register data */ struct REGDATA { unsigned int start; unsigned int stop; @@ -183,7 +183,7 @@ struct snd_ali_channel_control { unsigned int ainten; } data; - // register addresses + /* register addresses */ struct REGS { unsigned int start; unsigned int stop; @@ -197,19 +197,18 @@ struct snd_ali_channel_control { struct snd_ali_voice { unsigned int number; - unsigned int use: 1, - pcm: 1, - midi: 1, - mode: 1, - synth: 1; + unsigned int use :1, + pcm :1, + midi :1, + mode :1, + synth :1, + running :1; /* PCM data */ struct snd_ali *codec; struct snd_pcm_substream *substream; struct snd_ali_voice *extra; - unsigned int running: 1; - int eso; /* final ESO value for channel */ int count; /* runtime->period_size */ @@ -231,14 +230,12 @@ struct snd_alidev { }; -#ifdef CONFIG_PM #define ALI_GLOBAL_REGS 56 #define ALI_CHANNEL_REGS 8 struct snd_ali_image { - unsigned long regs[ALI_GLOBAL_REGS]; - unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; + u32 regs[ALI_GLOBAL_REGS]; + u32 channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; }; -#endif struct snd_ali { @@ -246,8 +243,8 @@ struct snd_ali { unsigned long port; unsigned char revision; - unsigned int hw_initialized: 1; - unsigned int spdif_support: 1; + unsigned int hw_initialized :1; + unsigned int spdif_support :1; struct pci_dev *pci; struct pci_dev *pci_m1533; @@ -287,108 +284,28 @@ MODULE_DEVICE_TABLE(pci, snd_ali_ids); static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int); static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short); -static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, unsigned short); - -/* - * Debug Part - */ - -#ifdef ALI_DEBUG - -static void ali_read_regs(struct snd_ali *codec, int channel) -{ - int i,j; - unsigned int dwVal; - - printk("channel %d registers map:\n", channel); - outb((unsigned char)(channel & 0x001f), ALI_REG(codec,ALI_GC_CIR)); - - printk(" "); - for(j=0;j<8;j++) - printk("%2.2x ", j*4); - printk("\n"); - - for (i=0; i<=0xf8/4;i++) { - if(i%8 == 0) - printk("%2.2x ", (i*4/0x10)*0x10); - dwVal = inl(ALI_REG(codec,i*4)); - printk("%8.8x ", dwVal); - if ((i+1)%8 == 0) - printk("\n"); - } - printk("\n"); -} -static void ali_read_cfg(unsigned int vendor, unsigned deviceid) -{ - unsigned int dwVal; - struct pci_dev *pci_dev; - int i,j; - - pci_dev = pci_get_device(vendor, deviceid, NULL); - if (pci_dev == NULL) - return ; - - printk("\nM%x PCI CFG\n", deviceid); - printk(" "); - for(j=0;j<8;j++) - printk("%d ",j); - printk("\n"); - - for(i=0;i<8;i++) { - printk("%d ",i); - for(j=0;j<8;j++) - { - pci_read_config_dword(pci_dev, i*0x20+j*4, &dwVal); - printk("%8.8x ", dwVal); - } - printk("\n"); - } - pci_dev_put(pci_dev); - } -static void ali_read_ac97regs(struct snd_ali *codec, int secondary) -{ - unsigned short i,j; - unsigned short wVal; - - printk("\ncodec %d registers map:\n", secondary); - - printk(" "); - for(j=0;j<8;j++) - printk("%2.2x ",j*2); - printk("\n"); - - for (i=0; i<64;i++) { - if(i%8 == 0) - printk("%2.2x ", (i/8)*0x10); - wVal = snd_ali_codec_peek(codec, secondary, i*2); - printk("%4.4x ", wVal); - if ((i+1)%8 == 0) - printk("\n"); - } - printk("\n"); -} - -#endif +static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, + unsigned short); /* * AC97 ACCESS */ static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec, - unsigned int port ) + unsigned int port) { return (unsigned int)inl(ALI_REG(codec, port)); } -static inline void snd_ali_5451_poke( struct snd_ali *codec, - unsigned int port, - unsigned int val ) +static inline void snd_ali_5451_poke(struct snd_ali *codec, + unsigned int port, + unsigned int val) { outl((unsigned int)val, ALI_REG(codec, port)); } -static int snd_ali_codec_ready( struct snd_ali *codec, - unsigned int port ) +static int snd_ali_codec_ready(struct snd_ali *codec, + unsigned int port) { unsigned long end_time; unsigned int res; @@ -396,7 +313,7 @@ static int snd_ali_codec_ready( struct snd_ali *codec, end_time = jiffies + msecs_to_jiffies(250); do { res = snd_ali_5451_peek(codec,port); - if (! (res & 0x8000)) + if (!(res & 0x8000)) return 0; schedule_timeout_uninterruptible(1); } while (time_after_eq(end_time, jiffies)); @@ -425,11 +342,11 @@ static int snd_ali_stimer_ready(struct snd_ali *codec) } static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, - unsigned short reg, - unsigned short val) + unsigned short reg, + unsigned short val) { - unsigned int dwVal = 0; - unsigned int port = 0; + unsigned int dwVal; + unsigned int port; if (reg >= 0x80) { snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg); @@ -445,20 +362,22 @@ static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, dwVal = (unsigned int) (reg & 0xff); dwVal |= 0x8000 | (val << 16); - if (secondary) dwVal |= 0x0080; - if (codec->revision == ALI_5451_V02) dwVal |= 0x0100; + if (secondary) + dwVal |= 0x0080; + if (codec->revision == ALI_5451_V02) + dwVal |= 0x0100; - snd_ali_5451_poke(codec,port,dwVal); + snd_ali_5451_poke(codec, port, dwVal); return ; } -static unsigned short snd_ali_codec_peek( struct snd_ali *codec, - int secondary, - unsigned short reg) +static unsigned short snd_ali_codec_peek(struct snd_ali *codec, + int secondary, + unsigned short reg) { - unsigned int dwVal = 0; - unsigned int port = 0; + unsigned int dwVal; + unsigned int port; if (reg >= 0x80) { snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg); @@ -474,7 +393,8 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec, dwVal = (unsigned int) (reg & 0xff); dwVal |= 0x8000; /* bit 15*/ - if (secondary) dwVal |= 0x0080; + if (secondary) + dwVal |= 0x0080; snd_ali_5451_poke(codec, port, dwVal); @@ -483,7 +403,7 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec, if (snd_ali_codec_ready(codec, port) < 0) return ~0; - return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16; + return (snd_ali_5451_peek(codec, port) & 0xffff0000) >> 16; } static void snd_ali_codec_write(struct snd_ac97 *ac97, @@ -493,9 +413,9 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97, struct snd_ali *codec = ac97->private_data; snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val); - if(reg == AC97_GPIO_STATUS) { - outl((val << ALI_AC97_GPIO_DATA_SHIFT)|ALI_AC97_GPIO_ENABLE, - ALI_REG(codec, ALI_AC97_GPIO)); + if (reg == AC97_GPIO_STATUS) { + outl((val << ALI_AC97_GPIO_DATA_SHIFT) | ALI_AC97_GPIO_ENABLE, + ALI_REG(codec, ALI_AC97_GPIO)); return; } snd_ali_codec_poke(codec, ac97->num, reg, val); @@ -503,12 +423,13 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97, } -static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg) +static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, + unsigned short reg) { struct snd_ali *codec = ac97->private_data; snd_ali_printk("codec_read reg=%xh.\n", reg); - return (snd_ali_codec_peek(codec, ac97->num, reg)); + return snd_ali_codec_peek(codec, ac97->num, reg); } /* @@ -517,11 +438,12 @@ static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short r static int snd_ali_reset_5451(struct snd_ali *codec) { - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; unsigned short wCount, wReg; unsigned int dwVal; - if ((pci_dev = codec->pci_m1533) != NULL) { + pci_dev = codec->pci_m1533; + if (pci_dev) { pci_read_config_dword(pci_dev, 0x7c, &dwVal); pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000); udelay(5000); @@ -541,7 +463,7 @@ static int snd_ali_reset_5451(struct snd_ali *codec) wCount = 200; while(wCount--) { wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN); - if((wReg & 0x000f) == 0x000f) + if ((wReg & 0x000f) == 0x000f) return 0; udelay(5000); } @@ -555,8 +477,8 @@ static int snd_ali_reset_5451(struct snd_ali *codec) static int snd_ali_reset_codec(struct snd_ali *codec) { - struct pci_dev *pci_dev = NULL; - unsigned char bVal = 0; + struct pci_dev *pci_dev; + unsigned char bVal; unsigned int dwVal; unsigned short wCount, wReg; @@ -579,9 +501,9 @@ static int snd_ali_reset_codec(struct snd_ali *codec) udelay(15000); wCount = 200; - while(wCount--) { + while (wCount--) { wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN); - if((wReg & 0x000f) == 0x000f) + if ((wReg & 0x000f) == 0x000f) return 0; udelay(5000); } @@ -594,25 +516,27 @@ static int snd_ali_reset_codec(struct snd_ali *codec) * ALI 5451 Controller */ -static void snd_ali_enable_special_channel(struct snd_ali *codec, unsigned int channel) +static void snd_ali_enable_special_channel(struct snd_ali *codec, + unsigned int channel) { - unsigned long dwVal = 0; + unsigned long dwVal; - dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL)); + dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)); dwVal |= 1 << (channel & 0x0000001f); - outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL)); + outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); } -static void snd_ali_disable_special_channel(struct snd_ali *codec, unsigned int channel) +static void snd_ali_disable_special_channel(struct snd_ali *codec, + unsigned int channel) { - unsigned long dwVal = 0; + unsigned long dwVal; - dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL)); + dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)); dwVal &= ~(1 << (channel & 0x0000001f)); - outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL)); + outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); } -static void snd_ali_enable_address_interrupt(struct snd_ali * codec) +static void snd_ali_enable_address_interrupt(struct snd_ali *codec) { unsigned int gc; @@ -622,7 +546,7 @@ static void snd_ali_enable_address_interrupt(struct snd_ali * codec) outl( gc, ALI_REG(codec, ALI_GC_CIR)); } -static void snd_ali_disable_address_interrupt(struct snd_ali * codec) +static void snd_ali_disable_address_interrupt(struct snd_ali *codec) { unsigned int gc; @@ -632,8 +556,9 @@ static void snd_ali_disable_address_interrupt(struct snd_ali * codec) outl(gc, ALI_REG(codec, ALI_GC_CIR)); } -#if 0 // not used -static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel) +#if 0 /* not used */ +static void snd_ali_enable_voice_irq(struct snd_ali *codec, + unsigned int channel) { unsigned int mask; struct snd_ali_channel_control *pchregs = &(codec->chregs); @@ -641,13 +566,14 @@ static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel snd_ali_printk("enable_voice_irq channel=%d\n",channel); mask = 1 << (channel & 0x1f); - pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten)); + pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten)); pchregs->data.ainten |= mask; - outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten)); + outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten)); } #endif -static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channel) +static void snd_ali_disable_voice_irq(struct snd_ali *codec, + unsigned int channel) { unsigned int mask; struct snd_ali_channel_control *pchregs = &(codec->chregs); @@ -655,9 +581,9 @@ static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channe snd_ali_printk("disable_voice_irq channel=%d\n",channel); mask = 1 << (channel & 0x1f); - pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten)); + pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten)); pchregs->data.ainten &= ~mask; - outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten)); + outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten)); } static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) @@ -665,7 +591,8 @@ static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) unsigned int idx = channel & 0x1f; if (codec->synth.chcnt >= ALI_CHANNELS){ - snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n"); + snd_printk(KERN_ERR + "ali_alloc_pcm_channel: no free channels.\n"); return -1; } @@ -685,35 +612,41 @@ static int snd_ali_find_free_channel(struct snd_ali * codec, int rec) snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm"); - // recording + /* recording */ if (rec) { if (codec->spdif_support && - (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT)) + (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & + ALI_SPDIF_IN_SUPPORT)) idx = ALI_SPDIF_IN_CHANNEL; else idx = ALI_PCM_IN_CHANNEL; - if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { + result = snd_ali_alloc_pcm_channel(codec, idx); + if (result >= 0) return result; - } else { - snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n"); + else { + snd_printk(KERN_ERR "ali_find_free_channel: " + "record channel is busy now.\n"); return -1; } } - //playback... + /* playback... */ if (codec->spdif_support && - (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)) { + (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & + ALI_SPDIF_OUT_CH_ENABLE)) { idx = ALI_SPDIF_OUT_CHANNEL; - if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { + result = snd_ali_alloc_pcm_channel(codec, idx); + if (result >= 0) return result; - } else { - snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n"); - } + else + snd_printk(KERN_ERR "ali_find_free_channel: " + "S/PDIF out channel is in busy now.\n"); } for (idx = 0; idx < ALI_CHANNELS; idx++) { - if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) + result = snd_ali_alloc_pcm_channel(codec, idx); + if (result >= 0) return result; } snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n"); @@ -730,7 +663,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) return; if (!(codec->synth.chmap & (1 << idx))) { - snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel); + snd_printk(KERN_ERR "ali_free_channel_pcm: " + "channel %d is not in use.\n", channel); return; } else { codec->synth.chmap &= ~(1 << idx); @@ -738,8 +672,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) } } -#if 0 // not used -static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel) +#if 0 /* not used */ +static void snd_ali_start_voice(struct snd_ali *codec, unsigned int channel) { unsigned int mask = 1 << (channel & 0x1f); @@ -748,7 +682,7 @@ static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel) } #endif -static void snd_ali_stop_voice(struct snd_ali * codec, unsigned int channel) +static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel) { unsigned int mask = 1 << (channel & 0x1f); @@ -768,26 +702,27 @@ static void snd_ali_delay(struct snd_ali *codec,int interval) currenttimer = inl(ALI_REG(codec, ALI_STIMER)); while (currenttimer < begintimer + interval) { - if(snd_ali_stimer_ready(codec) < 0) + if (snd_ali_stimer_ready(codec) < 0) break; currenttimer = inl(ALI_REG(codec, ALI_STIMER)); + cpu_relax(); } } static void snd_ali_detect_spdif_rate(struct snd_ali *codec) { - u16 wval = 0; + u16 wval; u16 count = 0; - u8 bval = 0, R1 = 0, R2 = 0; + u8 bval, R1 = 0, R2; - bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); + bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1)); bval |= 0x1F; - outb(bval,ALI_REG(codec,ALI_SPDIF_CTRL + 1)); + outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL + 1)); - while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000) { + while ((R1 < 0x0b || R1 > 0x0e) && R1 != 0x12 && count <= 50000) { count ++; snd_ali_delay(codec, 6); - bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); + bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1)); R1 = bval & 0x1F; } @@ -801,7 +736,10 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) snd_ali_delay(codec, 6); bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); R2 = bval & 0x1F; - if (R2 != R1) R1 = R2; else break; + if (R2 != R1) + R1 = R2; + else + break; } if (count > 50000) { @@ -810,42 +748,45 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) } if (R2 >= 0x0b && R2 <= 0x0e) { - wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2)); - wval &= 0xE0F0; - wval |= (u16)0x09 << 8 | (u16)0x05; - outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2)); + wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2)); + wval &= 0xe0f0; + wval |= (0x09 << 8) | 0x05; + outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2)); - bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0; - outb(bval|0x02,ALI_REG(codec,ALI_SPDIF_CS + 3)); + bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)) & 0xf0; + outb(bval | 0x02, ALI_REG(codec, ALI_SPDIF_CS + 3)); } else if (R2 == 0x12) { - wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2)); - wval &= 0xE0F0; - wval |= (u16)0x0E << 8 | (u16)0x08; - outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2)); + wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2)); + wval &= 0xe0f0; + wval |= (0x0e << 8) | 0x08; + outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2)); - bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0; - outb(bval|0x03,ALI_REG(codec,ALI_SPDIF_CS + 3)); + bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)) & 0xf0; + outb(bval | 0x03, ALI_REG(codec, ALI_SPDIF_CS + 3)); } } static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec) { - u32 dwRate = 0; - u8 bval = 0; + u32 dwRate; + u8 bval; - bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL)); - bval &= 0x7F; + bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); + bval &= 0x7f; bval |= 0x40; - outb(bval, ALI_REG(codec,ALI_SPDIF_CTRL)); + outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL)); snd_ali_detect_spdif_rate(codec); - bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)); - bval &= 0x0F; + bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)); + bval &= 0x0f; - if (bval == 0) dwRate = 44100; - if (bval == 1) dwRate = 48000; - if (bval == 2) dwRate = 32000; + switch (bval) { + case 0: dwRate = 44100; break; + case 1: dwRate = 48000; break; + case 2: dwRate = 32000; break; + default: dwRate = 0; break; + } return dwRate; } @@ -880,20 +821,22 @@ static void snd_ali_disable_spdif_in(struct snd_ali *codec) static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate) { unsigned char bVal; - unsigned int dwRate = 0; + unsigned int dwRate; - if (rate == 32000) dwRate = 0x300; - if (rate == 44100) dwRate = 0; - if (rate == 48000) dwRate = 0x200; + switch (rate) { + case 32000: dwRate = 0x300; break; + case 48000: dwRate = 0x200; break; + default: dwRate = 0; break; + } bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); bVal &= (unsigned char)(~(1<<6)); - bVal |= 0x80; //select right + bVal |= 0x80; /* select right */ outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2)); - bVal &= (~0x80); //select left + bVal &= ~0x80; /* select left */ outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2)); } @@ -902,8 +845,7 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec) { unsigned short wVal; unsigned char bVal; - - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; pci_dev = codec->pci_m1533; if (pci_dev == NULL) @@ -926,17 +868,15 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec) bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL)); - { - wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); - wVal |= ALI_SPDIF_OUT_SEL_PCM; - outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); - snd_ali_disable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL); - } + wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); + wVal |= ALI_SPDIF_OUT_SEL_PCM; + outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); + snd_ali_disable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL); } static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) { - unsigned short wVal = 0; + unsigned short wVal; wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); wVal &= ~ALI_SPDIF_OUT_SEL_PCM; @@ -949,12 +889,13 @@ static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) wVal &= (~0x0002); outw(wVal, ALI_REG(codec, ALI_SPDIF_CS)); */ - snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL); + snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL); } static void snd_ali_disable_spdif_chnout(struct snd_ali *codec) { - unsigned short wVal = 0; + unsigned short wVal; + wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); wVal |= ALI_SPDIF_OUT_SEL_PCM; outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); @@ -972,11 +913,11 @@ static void snd_ali_disable_spdif_out(struct snd_ali *codec) snd_ali_disable_spdif_chnout(codec); } -static void snd_ali_update_ptr(struct snd_ali *codec,int channel) +static void snd_ali_update_ptr(struct snd_ali *codec, int channel) { - struct snd_ali_voice *pvoice = NULL; + struct snd_ali_voice *pvoice; struct snd_pcm_runtime *runtime; - struct snd_ali_channel_control *pchregs = NULL; + struct snd_ali_channel_control *pchregs; unsigned int old, mask; #ifdef ALI_DEBUG unsigned int temp, cspf; @@ -984,9 +925,9 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) pchregs = &(codec->chregs); - // check if interrupt occurred for channel + /* check if interrupt occurred for channel */ old = pchregs->data.aint; - mask = ((unsigned int) 1L) << (channel & 0x1f); + mask = 1U << (channel & 0x1f); if (!(old & mask)) return; @@ -1005,7 +946,8 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask; #endif if (pvoice->running) { - snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",(u16)temp,cspf); + snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n", + (u16)temp, cspf); spin_unlock(&codec->reg_lock); snd_pcm_period_elapsed(pvoice->substream); spin_lock(&codec->reg_lock); @@ -1027,49 +969,47 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) pchregs->data.aint = old & (~mask); } -static void snd_ali_interrupt(struct snd_ali * codec) +static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) { + struct snd_ali *codec = dev_id; int channel; unsigned int audio_int; - struct snd_ali_channel_control *pchregs = NULL; - pchregs = &(codec->chregs); + struct snd_ali_channel_control *pchregs; + + if (codec == NULL || !codec->hw_initialized) + return IRQ_NONE; audio_int = inl(ALI_REG(codec, ALI_MISCINT)); + if (!audio_int) + return IRQ_NONE; + + pchregs = &(codec->chregs); if (audio_int & ADDRESS_IRQ) { - // get interrupt status for all channels - pchregs->data.aint = inl(ALI_REG(codec,pchregs->regs.aint)); - for (channel = 0; channel < ALI_CHANNELS; channel++) { + /* get interrupt status for all channels */ + pchregs->data.aint = inl(ALI_REG(codec, pchregs->regs.aint)); + for (channel = 0; channel < ALI_CHANNELS; channel++) snd_ali_update_ptr(codec, channel); - } } outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), - ALI_REG(codec,ALI_MISCINT)); -} - - -static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) -{ - struct snd_ali *codec = dev_id; + ALI_REG(codec, ALI_MISCINT)); - if (codec == NULL) - return IRQ_NONE; - snd_ali_interrupt(codec); return IRQ_HANDLED; } -static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int type, int rec, int channel) +static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, + int type, int rec, int channel) { - struct snd_ali_voice *pvoice = NULL; + struct snd_ali_voice *pvoice; int idx; - snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec); + snd_ali_printk("alloc_voice: type=%d rec=%d\n", type, rec); spin_lock_irq(&codec->voice_alloc); if (type == SNDRV_ALI_VOICE_TYPE_PCM) { idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) : snd_ali_find_free_channel(codec,rec); - if(idx < 0) { + if (idx < 0) { snd_printk(KERN_ERR "ali_alloc_voice: err.\n"); spin_unlock_irq(&codec->voice_alloc); return NULL; @@ -1087,7 +1027,8 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int typ } -static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvoice) +static void snd_ali_free_voice(struct snd_ali * codec, + struct snd_ali_voice *pvoice) { void (*private_free)(void *); void *private_data; @@ -1101,9 +1042,8 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo private_data = pvoice->private_data; pvoice->private_free = NULL; pvoice->private_data = NULL; - if (pvoice->pcm) { + if (pvoice->pcm) snd_ali_free_channel_pcm(codec, pvoice->number); - } pvoice->use = pvoice->pcm = pvoice->synth = 0; pvoice->substream = NULL; spin_unlock_irq(&codec->voice_alloc); @@ -1112,9 +1052,9 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo } -static void snd_ali_clear_voices(struct snd_ali * codec, - unsigned int v_min, - unsigned int v_max) +static void snd_ali_clear_voices(struct snd_ali *codec, + unsigned int v_min, + unsigned int v_max) { unsigned int i; @@ -1124,7 +1064,7 @@ static void snd_ali_clear_voices(struct snd_ali * codec, } } -static void snd_ali_write_voice_regs(struct snd_ali * codec, +static void snd_ali_write_voice_regs(struct snd_ali *codec, unsigned int Channel, unsigned int LBA, unsigned int CSO, @@ -1139,7 +1079,7 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec, { unsigned int ctlcmds[4]; - outb((unsigned char)(Channel & 0x001f),ALI_REG(codec,ALI_GC_CIR)); + outb((unsigned char)(Channel & 0x001f), ALI_REG(codec, ALI_GC_CIR)); ctlcmds[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff); ctlcmds[1] = LBA; @@ -1152,10 +1092,10 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec, outb(Channel, ALI_REG(codec, ALI_GC_CIR)); - outl(ctlcmds[0], ALI_REG(codec,ALI_CSO_ALPHA_FMS)); - outl(ctlcmds[1], ALI_REG(codec,ALI_LBA)); - outl(ctlcmds[2], ALI_REG(codec,ALI_ESO_DELTA)); - outl(ctlcmds[3], ALI_REG(codec,ALI_GVSEL_PAN_VOC_CTRL_EC)); + outl(ctlcmds[0], ALI_REG(codec, ALI_CSO_ALPHA_FMS)); + outl(ctlcmds[1], ALI_REG(codec, ALI_LBA)); + outl(ctlcmds[2], ALI_REG(codec, ALI_ESO_DELTA)); + outl(ctlcmds[3], ALI_REG(codec, ALI_GVSEL_PAN_VOC_CTRL_EC)); outl(0x30000000, ALI_REG(codec, ALI_EBUF1)); /* Still Mode */ outl(0x30000000, ALI_REG(codec, ALI_EBUF2)); /* Still Mode */ @@ -1165,8 +1105,10 @@ static unsigned int snd_ali_convert_rate(unsigned int rate, int rec) { unsigned int delta; - if (rate < 4000) rate = 4000; - if (rate > 48000) rate = 48000; + if (rate < 4000) + rate = 4000; + if (rate > 48000) + rate = 48000; if (rec) { if (rate == 44100) @@ -1201,11 +1143,11 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream) */ CTRL = 0x00000001; if (snd_pcm_format_width(runtime->format) == 16) - CTRL |= 0x00000008; // 16-bit data + CTRL |= 0x00000008; /* 16-bit data */ if (!snd_pcm_format_unsigned(runtime->format)) - CTRL |= 0x00000002; // signed data + CTRL |= 0x00000002; /* signed data */ if (runtime->channels > 1) - CTRL |= 0x00000004; // stereo data + CTRL |= 0x00000004; /* stereo data */ return CTRL; } @@ -1213,12 +1155,6 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream) * PCM part */ -static int snd_ali_ioctl(struct snd_pcm_substream *substream, - unsigned int cmd, void *arg) -{ - return snd_pcm_lib_ioctl(substream, cmd, arg); -} - static int snd_ali_trigger(struct snd_pcm_substream *substream, int cmd) @@ -1226,17 +1162,19 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_substream *s; unsigned int what, whati, capture_flag; - struct snd_ali_voice *pvoice = NULL, *evoice = NULL; + struct snd_ali_voice *pvoice, *evoice; unsigned int val; int do_start; switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: - do_start = 1; break; + do_start = 1; + break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: - do_start = 0; break; + do_start = 0; + break; default: return -EINVAL; } @@ -1247,9 +1185,9 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, pvoice = s->runtime->private_data; evoice = pvoice->extra; what |= 1 << (pvoice->number & 0x1f); - if (evoice == NULL) { + if (evoice == NULL) whati |= 1 << (pvoice->number & 0x1f); - } else { + else { whati |= 1 << (evoice->number & 0x1f); what |= 1 << (evoice->number & 0x1f); } @@ -1268,48 +1206,51 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, } } spin_lock(&codec->reg_lock); - if (! do_start) { + if (!do_start) outl(what, ALI_REG(codec, ALI_STOP)); - } val = inl(ALI_REG(codec, ALI_AINTEN)); - if (do_start) { + if (do_start) val |= whati; - } else { + else val &= ~whati; - } outl(val, ALI_REG(codec, ALI_AINTEN)); - if (do_start) { + if (do_start) outl(what, ALI_REG(codec, ALI_START)); - } - snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati); + snd_ali_printk("trigger: what=%xh whati=%xh\n", what, whati); spin_unlock(&codec->reg_lock); return 0; } static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) + struct snd_pcm_hw_params *hw_params) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ali_voice *pvoice = runtime->private_data; struct snd_ali_voice *evoice = pvoice->extra; int err; - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); - if (err < 0) return err; + + err = snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); + if (err < 0) + return err; /* voice management */ - if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) { - if (evoice == NULL) { - evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1); - if (evoice == NULL) + if (params_buffer_size(hw_params) / 2 != + params_period_size(hw_params)) { + if (!evoice) { + evoice = snd_ali_alloc_voice(codec, + SNDRV_ALI_VOICE_TYPE_PCM, + 0, -1); + if (!evoice) return -ENOMEM; pvoice->extra = evoice; evoice->substream = substream; } } else { - if (evoice != NULL) { + if (!evoice) { snd_ali_free_voice(codec, evoice); pvoice->extra = evoice = NULL; } @@ -1326,7 +1267,7 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL; snd_pcm_lib_free_pages(substream); - if (evoice != NULL) { + if (!evoice) { snd_ali_free_voice(codec, evoice); pvoice->extra = NULL; } @@ -1334,9 +1275,10 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) } static int snd_ali_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) + struct snd_pcm_hw_params *hw_params) { - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); + return snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); } static int snd_ali_hw_free(struct snd_pcm_substream *substream) @@ -1367,12 +1309,13 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) /* set Delta (rate) value */ Delta = snd_ali_convert_rate(runtime->rate, 0); - if ((pvoice->number == ALI_SPDIF_IN_CHANNEL) || - (pvoice->number == ALI_PCM_IN_CHANNEL)) + if (pvoice->number == ALI_SPDIF_IN_CHANNEL || + pvoice->number == ALI_PCM_IN_CHANNEL) snd_ali_disable_special_channel(codec, pvoice->number); else if (codec->spdif_support && - (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE) - && (pvoice->number == ALI_SPDIF_OUT_CHANNEL)) { + (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & + ALI_SPDIF_OUT_CH_ENABLE) + && pvoice->number == ALI_SPDIF_OUT_CHANNEL) { snd_ali_set_spdif_out_rate(codec, runtime->rate); Delta = 0x1000; } @@ -1386,7 +1329,8 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) /* set target ESO for channel */ pvoice->eso = runtime->buffer_size; - snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",pvoice->eso,pvoice->count); + snd_ali_printk("playback_prepare: eso=%xh count=%xh\n", + pvoice->eso, pvoice->count); /* set ESO to capture first MIDLP interrupt */ ESO = pvoice->eso -1; @@ -1397,35 +1341,37 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) PAN = 0; VOL = 0; EC = 0; - snd_ali_printk("playback_prepare:\n ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL); - snd_ali_write_voice_regs( codec, - pvoice->number, - LBA, - 0, /* cso */ - ESO, - Delta, - 0, /* alpha */ - GVSEL, - PAN, - VOL, - CTRL, - EC); - if (evoice != NULL) { + snd_ali_printk("playback_prepare:\n"); + snd_ali_printk("ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n", + pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL); + snd_ali_write_voice_regs(codec, + pvoice->number, + LBA, + 0, /* cso */ + ESO, + Delta, + 0, /* alpha */ + GVSEL, + PAN, + VOL, + CTRL, + EC); + if (!evoice) { evoice->count = pvoice->count; evoice->eso = pvoice->count << 1; ESO = evoice->eso - 1; snd_ali_write_voice_regs(codec, - evoice->number, - LBA, - 0, /* cso */ - ESO, - Delta, - 0, /* alpha */ - GVSEL, - (unsigned int)0x7f, - (unsigned int)0x3ff, - CTRL, - EC); + evoice->number, + LBA, + 0, /* cso */ + ESO, + Delta, + 0, /* alpha */ + GVSEL, + 0x7f, + 0x3ff, + CTRL, + EC); } spin_unlock_irq(&codec->reg_lock); return 0; @@ -1457,7 +1403,7 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) pvoice->number == ALI_MODEM_OUT_CHANNEL) ? 0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode); - // Prepare capture intr channel + /* Prepare capture intr channel */ if (pvoice->number == ALI_SPDIF_IN_CHANNEL) { unsigned int rate; @@ -1468,7 +1414,8 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) rate = snd_ali_get_spdif_in_rate(codec); if (rate == 0) { - snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n"); + snd_printk(KERN_WARNING "ali_capture_preapre: " + "spdif rate detect err!\n"); rate = 48000; } spin_lock_irq(&codec->reg_lock); @@ -1479,19 +1426,19 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) } if (rate != 48000) - Delta = ((rate << 12)/runtime->rate)&0x00ffff; + Delta = ((rate << 12) / runtime->rate) & 0x00ffff; } - // set target ESO for channel + /* set target ESO for channel */ pvoice->eso = runtime->buffer_size; - // set interrupt count size + /* set interrupt count size */ pvoice->count = runtime->period_size; - // set Loop Back Address + /* set Loop Back Address */ LBA = runtime->dma_addr; - // set ESO to capture first MIDLP interrupt + /* set ESO to capture first MIDLP interrupt */ ESO = pvoice->eso - 1; CTRL = snd_ali_control_mode(substream); GVSEL = 0; @@ -1512,14 +1459,14 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) CTRL, EC); - spin_unlock_irq(&codec->reg_lock); return 0; } -static snd_pcm_uframes_t snd_ali_playback_pointer(struct snd_pcm_substream *substream) +static snd_pcm_uframes_t +snd_ali_playback_pointer(struct snd_pcm_substream *substream) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; @@ -1561,14 +1508,14 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream) static struct snd_pcm_hardware snd_ali_playback = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, .rate_min = 4000, .rate_max = 48000, .channels_min = 1, @@ -1587,14 +1534,14 @@ static struct snd_pcm_hardware snd_ali_playback = static struct snd_pcm_hardware snd_ali_capture = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, .rate_min = 4000, .rate_max = 48000, .channels_min = 1, @@ -1618,15 +1565,16 @@ static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime) } } -static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channel, - struct snd_pcm_hardware *phw) +static int snd_ali_open(struct snd_pcm_substream *substream, int rec, + int channel, struct snd_pcm_hardware *phw) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ali_voice *pvoice; - pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel); - if (pvoice == NULL) + pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, + channel); + if (!pvoice) return -EAGAIN; pvoice->substream = substream; @@ -1635,7 +1583,8 @@ static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channe runtime->hw = *phw; snd_pcm_set_sync(substream); - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); + snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, + 0, 64*1024); return 0; } @@ -1667,7 +1616,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream) static struct snd_pcm_ops snd_ali_playback_ops = { .open = snd_ali_playback_open, .close = snd_ali_playback_close, - .ioctl = snd_ali_ioctl, + .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ali_playback_hw_params, .hw_free = snd_ali_playback_hw_free, .prepare = snd_ali_playback_prepare, @@ -1678,7 +1627,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = { static struct snd_pcm_ops snd_ali_capture_ops = { .open = snd_ali_capture_open, .close = snd_ali_close, - .ioctl = snd_ali_ioctl, + .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ali_hw_params, .hw_free = snd_ali_hw_free, .prepare = snd_ali_prepare, @@ -1695,20 +1644,22 @@ static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream, { struct snd_ali *chip = snd_pcm_substream_chip(substream); unsigned int modem_num = chip->num_of_codecs - 1; - snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params)); + snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, + params_rate(hw_params)); snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0); return snd_ali_hw_params(substream, hw_params); } static struct snd_pcm_hardware snd_ali_modem = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_KNOT|SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000, + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000), .rate_min = 8000, .rate_max = 16000, .channels_min = 1, @@ -1721,15 +1672,17 @@ static struct snd_pcm_hardware snd_ali_modem = .fifo_size = 0, }; -static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, int channel) +static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, + int channel) { - static unsigned int rates [] = {8000,9600,12000,16000}; + static unsigned int rates[] = {8000, 9600, 12000, 16000}; static struct snd_pcm_hw_constraint_list hw_constraint_rates = { .count = ARRAY_SIZE(rates), .list = rates, .mask = 0, }; int err = snd_ali_open(substream, rec, channel, &snd_ali_modem); + if (err) return err; return snd_pcm_hw_constraint_list(substream->runtime, 0, @@ -1786,7 +1739,8 @@ static void snd_ali_pcm_free(struct snd_pcm *pcm) } -static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_pcm_description *desc) +static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, + struct ali_pcm_description *desc) { struct snd_pcm *pcm; int err; @@ -1800,12 +1754,15 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_ pcm->private_data = codec; pcm->private_free = snd_ali_pcm_free; if (desc->playback_ops) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + desc->playback_ops); if (desc->capture_ops) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + desc->capture_ops); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(codec->pci), 64*1024, 128*1024); + snd_dma_pci_data(codec->pci), + 64*1024, 128*1024); pcm->info_flags = 0; pcm->dev_class = desc->class; @@ -1816,16 +1773,29 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_ } static struct ali_pcm_description ali_pcms[] = { - { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops }, - { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM } + { .name = "ALI 5451", + .playback_num = ALI_CHANNELS, + .capture_num = 1, + .playback_ops = &snd_ali_playback_ops, + .capture_ops = &snd_ali_capture_ops + }, + { .name = "ALI 5451 modem", + .playback_num = 1, + .capture_num = 1, + .playback_ops = &snd_ali_modem_playback_ops, + .capture_ops = &snd_ali_modem_capture_ops, + .class = SNDRV_PCM_CLASS_MODEM + } }; static int __devinit snd_ali_build_pcms(struct snd_ali *codec) { int i, err; - for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++) - if((err = snd_ali_pcm(codec, i, &ali_pcms[i])) < 0) + for (i = 0; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms); i++) { + err = snd_ali_pcm(codec, i, &ali_pcms[i]); + if (err < 0) return err; + } return 0; } @@ -1835,7 +1805,8 @@ static int __devinit snd_ali_build_pcms(struct snd_ali *codec) .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \ .put = snd_ali5451_spdif_put, .private_value = value} -static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; @@ -1844,7 +1815,8 @@ static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 0; } -static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ali *codec = kcontrol->private_data; unsigned int enable; @@ -1852,12 +1824,13 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e enable = ucontrol->value.integer.value[0] ? 1 : 0; spin_lock_irq(&codec->reg_lock); - switch(kcontrol->private_value) { + switch (kcontrol->private_value) { case 0: enable = (codec->spdif_mask & 0x02) ? 1 : 0; break; case 1: - enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0; + enable = ((codec->spdif_mask & 0x02) && + (codec->spdif_mask & 0x04)) ? 1 : 0; break; case 2: enable = (codec->spdif_mask & 0x01) ? 1 : 0; @@ -1870,7 +1843,8 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e return 0; } -static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ali *codec = kcontrol->private_data; unsigned int change = 0, enable = 0; @@ -1937,18 +1911,6 @@ static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = { ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2) }; -static void snd_ali_mixer_free_ac97_bus(struct snd_ac97_bus *bus) -{ - struct snd_ali *codec = bus->private_data; - codec->ac97_bus = NULL; -} - -static void snd_ali_mixer_free_ac97(struct snd_ac97 *ac97) -{ - struct snd_ali *codec = ac97->private_data; - codec->ac97[ac97->num] = NULL; -} - static int __devinit snd_ali_mixer(struct snd_ali * codec) { struct snd_ac97_template ac97; @@ -1959,19 +1921,20 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec) .read = snd_ali_codec_read, }; - if ((err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus)) < 0) + err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus); + if (err < 0) return err; - codec->ac97_bus->private_free = snd_ali_mixer_free_ac97_bus; memset(&ac97, 0, sizeof(ac97)); ac97.private_data = codec; - ac97.private_free = snd_ali_mixer_free_ac97; - for ( i = 0 ; i < codec->num_of_codecs ; i++) { + for (i = 0; i < codec->num_of_codecs; i++) { ac97.num = i; - if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) { - snd_printk(KERN_ERR "ali mixer %d creating error.\n", i); - if(i == 0) + err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i]); + if (err < 0) { + snd_printk(KERN_ERR + "ali mixer %d creating error.\n", i); + if (i == 0) return err; codec->num_of_codecs = 1; break; @@ -1979,9 +1942,11 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec) } if (codec->spdif_support) { - for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) { - err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); - if (err < 0) return err; + for (idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) { + err = snd_ctl_add(codec->card, + snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); + if (err < 0) + return err; } } return 0; @@ -1996,11 +1961,11 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) int i, j; im = chip->image; - if (! im) + if (!im) return 0; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for(i = 0 ; i < chip->num_of_codecs ; i++) { + for (i = 0; i < chip->num_of_codecs; i++) { snd_pcm_suspend_all(chip->pcm[i]); snd_ac97_suspend(chip->ac97[i]); } @@ -2008,10 +1973,10 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) spin_lock_irq(&chip->reg_lock); im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT)); - // im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); + /* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */ im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP)); - // disable all IRQ bits + /* disable all IRQ bits */ outl(0, ALI_REG(chip, ALI_MISCINT)); for (i = 0; i < ALI_GLOBAL_REGS; i++) { @@ -2026,7 +1991,7 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0)); } - // stop all HW channel + /* stop all HW channel */ outl(0xffffffff, ALI_REG(chip, ALI_STOP)); spin_unlock_irq(&chip->reg_lock); @@ -2045,7 +2010,7 @@ static int ali_resume(struct pci_dev *pci) int i, j; im = chip->image; - if (! im) + if (!im) return 0; pci_set_power_state(pci, PCI_D0); @@ -2067,19 +2032,20 @@ static int ali_resume(struct pci_dev *pci) } for (i = 0; i < ALI_GLOBAL_REGS; i++) { - if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START)) + if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || + (i*4 == ALI_START)) continue; outl(im->regs[i], ALI_REG(chip, i*4)); } - // start HW channel + /* start HW channel */ outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START)); - // restore IRQ enable bits + /* restore IRQ enable bits */ outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT)); spin_unlock_irq(&chip->reg_lock); - for(i = 0 ; i < chip->num_of_codecs ; i++) + for (i = 0 ; i < chip->num_of_codecs; i++) snd_ac97_resume(chip->ac97[i]); snd_power_change_state(card, SNDRV_CTL_POWER_D0); @@ -2111,7 +2077,7 @@ static int snd_ali_chip_init(struct snd_ali *codec) { unsigned int legacy; unsigned char temp; - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; snd_ali_printk("chip initializing ... \n"); @@ -2144,7 +2110,8 @@ static int snd_ali_chip_init(struct snd_ali *codec) outb(0x10, ALI_REG(codec, ALI_MPUR2)); codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID); - codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS); + codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, + AC97_EXTENDED_STATUS); if (codec->spdif_support) { snd_ali_enable_spdif_out(codec); codec->spdif_mask = 0x00000002; @@ -2156,8 +2123,9 @@ static int snd_ali_chip_init(struct snd_ali *codec) if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) { codec->num_of_codecs++; outl(inl(ALI_REG(codec, ALI_SCTRL)) | - (ALI_SCTRL_LINE_IN2|ALI_SCTRL_GPIO_IN2|ALI_SCTRL_LINE_OUT_EN), - ALI_REG(codec, ALI_SCTRL)); + (ALI_SCTRL_LINE_IN2 | ALI_SCTRL_GPIO_IN2 | + ALI_SCTRL_LINE_OUT_EN), + ALI_REG(codec, ALI_SCTRL)); } snd_ali_printk("chip initialize succeed.\n"); @@ -2166,18 +2134,19 @@ static int snd_ali_chip_init(struct snd_ali *codec) } /* proc for register dump */ -static void snd_ali_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) +static void snd_ali_proc_read(struct snd_info_entry *entry, + struct snd_info_buffer *buf) { struct snd_ali *codec = entry->private_data; int i; - for(i = 0 ; i < 256 ; i+= 4) + for (i = 0; i < 256 ; i+= 4) snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i))); } static void __devinit snd_ali_proc_init(struct snd_ali *codec) { struct snd_info_entry *entry; - if(!snd_card_proc_new(codec->card, "ali5451", &entry)) + if (!snd_card_proc_new(codec->card, "ali5451", &entry)) snd_info_set_text_ops(entry, codec, snd_ali_proc_read); } @@ -2186,7 +2155,8 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) int err; snd_ali_printk("resouces allocation ...\n"); - if ((err = pci_request_regions(codec->pci, "ALI 5451")) < 0) + err = pci_request_regions(codec->pci, "ALI 5451"); + if (err < 0) return err; codec->port = pci_resource_start(codec->pci, 0); @@ -2199,9 +2169,9 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) snd_ali_printk("resouces allocated.\n"); return 0; } -static int snd_ali_dev_free(struct snd_device *device) +static int snd_ali_dev_free(struct snd_device *device) { - struct snd_ali *codec=device->device_data; + struct snd_ali *codec = device->device_data; snd_ali_free(codec); return 0; } @@ -2224,17 +2194,20 @@ static int __devinit snd_ali_create(struct snd_card *card, snd_ali_printk("creating ...\n"); /* enable PCI device */ - if ((err = pci_enable_device(pci)) < 0) + err = pci_enable_device(pci); + if (err < 0) return err; /* check, if we can restrict PCI DMA transfers to 31 bits */ if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 || pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) { - snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n"); + snd_printk(KERN_ERR "architecture does not support " + "31bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; } - if ((codec = kzalloc(sizeof(*codec), GFP_KERNEL)) == NULL) { + codec = kzalloc(sizeof(*codec), GFP_KERNEL); + if (!codec) { pci_disable_device(pci); return -ENOMEM; } @@ -2291,21 +2264,22 @@ static int __devinit snd_ali_create(struct snd_card *card, /* M1533: southbridge */ codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL); - if (! codec->pci_m1533) { + if (!codec->pci_m1533) { snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n"); snd_ali_free(codec); return -ENODEV; } /* M7101: power management */ codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL); - if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) { + if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) { snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n"); snd_ali_free(codec); return -ENODEV; } snd_ali_printk("snd_device_new is called.\n"); - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) { + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops); + if (err < 0) { snd_ali_free(codec); return err; } @@ -2313,18 +2287,18 @@ static int __devinit snd_ali_create(struct snd_card *card, snd_card_set_dev(card, &pci->dev); /* initialise synth voices*/ - for (i = 0; i < ALI_CHANNELS; i++ ) { + for (i = 0; i < ALI_CHANNELS; i++) codec->synth.voices[i].number = i; - } - if ((err = snd_ali_chip_init(codec)) < 0) { + err = snd_ali_chip_init(codec); + if (err < 0) { snd_printk(KERN_ERR "ali create: chip init error.\n"); return err; } #ifdef CONFIG_PM codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL); - if (! codec->image) + if (!codec->image) snd_printk(KERN_WARNING "can't allocate apm buffer\n"); #endif @@ -2346,26 +2320,23 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, snd_ali_printk("probe ...\n"); card = snd_card_new(index, id, THIS_MODULE, 0); - if (card == NULL) + if (!card) return -ENOMEM; - if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ali_create(card, pci, pcm_channels, spdif, &codec); + if (err < 0) + goto error; card->private_data = codec; snd_ali_printk("mixer building ...\n"); - if ((err = snd_ali_mixer(codec)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ali_mixer(codec); + if (err < 0) + goto error; snd_ali_printk("pcm building ...\n"); - if ((err = snd_ali_build_pcms(codec)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ali_build_pcms(codec); + if (err < 0) + goto error; snd_ali_proc_init(codec); @@ -2376,12 +2347,16 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, card->shortname, codec->port, codec->irq); snd_ali_printk("register card.\n"); - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err < 0) + goto error; + pci_set_drvdata(pci, card); return 0; + + error: + snd_card_free(card); + return err; } static void __devexit snd_ali_remove(struct pci_dev *pci) -- cgit v0.10.2 From 6b97eb45f2edca51250b6c1e3142801f069245fe Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 5 Apr 2007 14:51:48 +0200 Subject: [ALSA] hda-codec - Fix SPDIF output Fix SPDIF output (at least on Realtek codecs). The DIGI_CONVERT verbs have to be reset before the PCM stream is set up. Otherwise the digital setup is screwed up. Also, check the AMP capability before setting AMP of the digital out widget. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index e768187..2c2fcdc 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1114,10 +1114,14 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn change = codec->spdif_ctls != val; if (change || codec->in_resume) { codec->spdif_ctls = val; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | - AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80)); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + val & 0xff); + if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | + AC_AMP_SET_OUTPUT | + ((val & 1) ? 0 : 0x80)); } mutex_unlock(&codec->spdif_mutex); return change; @@ -1886,6 +1890,21 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i * Multi-channel / digital-out PCM helper functions */ +/* setup SPDIF output stream */ +static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, + unsigned int stream_tag, unsigned int format) +{ + /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ + if (codec->spdif_ctls & AC_DIG1_ENABLE) + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); + snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); + /* turn on again (if needed) */ + if (codec->spdif_ctls & AC_DIG1_ENABLE) + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + codec->spdif_ctls & 0xff); +} + /* * open the digital out in the exclusive mode */ @@ -1901,6 +1920,18 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mo return 0; } +int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, + struct hda_multi_out *mout, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + mutex_lock(&codec->spdif_mutex); + setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format); + mutex_unlock(&codec->spdif_mutex); + return 0; +} + /* * release the digital out */ @@ -1942,9 +1973,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) { mout->dig_out_used = HDA_DIG_ANALOG_DUP; - /* setup digital receiver */ - snd_hda_codec_setup_stream(codec, mout->dig_out_nid, - stream_tag, 0, format); + setup_dig_out_stream(codec, mout->dig_out_nid, + stream_tag, format); } else { mout->dig_out_used = 0; snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 39718d6..3505a67 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -148,6 +148,11 @@ struct hda_multi_out { int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); +int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, + struct hda_multi_out *mout, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 9c241cc..fa194f2 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -192,6 +192,17 @@ static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct ad198x_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + /* * Analog capture */ @@ -250,7 +261,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { .nid = 0, /* fill later */ .ops = { .open = ad198x_dig_playback_pcm_open, - .close = ad198x_dig_playback_pcm_close + .close = ad198x_dig_playback_pcm_close, + .prepare = ad198x_dig_playback_pcm_prepare }, }; diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c index 831469d..b89db1b 100644 --- a/sound/pci/hda/patch_atihdmi.c +++ b/sound/pci/hda/patch_atihdmi.c @@ -94,6 +94,17 @@ static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct atihdmi_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + static struct hda_pcm_stream atihdmi_pcm_digital_playback = { .substreams = 1, .channels_min = 2, @@ -101,7 +112,8 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = { .nid = 0x2, /* NID to query formats and rates and setup streams */ .ops = { .open = atihdmi_dig_playback_pcm_open, - .close = atihdmi_dig_playback_pcm_close + .close = atihdmi_dig_playback_pcm_close, + .prepare = atihdmi_dig_playback_pcm_prepare }, }; diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 5b9d3a3..3c722e6 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -497,6 +497,17 @@ static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct cmi_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + /* * Analog capture */ @@ -556,7 +567,8 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = { /* NID is set in cmi9880_build_pcms */ .ops = { .open = cmi9880_dig_playback_pcm_open, - .close = cmi9880_dig_playback_pcm_close + .close = cmi9880_dig_playback_pcm_close, + .prepare = cmi9880_dig_playback_pcm_prepare }, }; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index efb95dc..2349b5e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -136,6 +136,18 @@ static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct conexant_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, + format, substream); +} + /* * Analog capture */ @@ -194,7 +206,8 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = { .nid = 0, /* fill later */ .ops = { .open = conexant_dig_playback_pcm_open, - .close = conexant_dig_playback_pcm_close + .close = conexant_dig_playback_pcm_close, + .prepare = conexant_dig_playback_pcm_prepare }, }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4243c6b..d3f7a3d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1916,6 +1916,17 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_open(codec, &spec->multiout); } +static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct alc_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream) @@ -1984,7 +1995,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = { /* NID is set in alc_build_pcms */ .ops = { .open = alc880_dig_playback_pcm_open, - .close = alc880_dig_playback_pcm_close + .close = alc880_dig_playback_pcm_close, + .prepare = alc880_dig_playback_pcm_prepare }, }; diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6dd4822..612d355 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -814,6 +814,17 @@ static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + /* * Analog capture callbacks @@ -848,7 +859,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { /* NID is set in stac92xx_build_pcms */ .ops = { .open = stac92xx_dig_playback_pcm_open, - .close = stac92xx_dig_playback_pcm_close + .close = stac92xx_dig_playback_pcm_close, + .prepare = stac92xx_dig_playback_pcm_prepare }, }; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 2b11ac8..ba32d1e 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -377,6 +377,17 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct via_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + /* * Analog capture */ @@ -433,7 +444,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = { /* NID is set in via_build_pcms */ .ops = { .open = via_dig_playback_pcm_open, - .close = via_dig_playback_pcm_close + .close = via_dig_playback_pcm_close, + .prepare = via_dig_playback_pcm_prepare }, }; -- cgit v0.10.2 From 208eee2a9db7e70109583e3481371967cd1d4764 Mon Sep 17 00:00:00 2001 From: Frederik Deweerdt Date: Thu, 5 Apr 2007 16:57:41 +0200 Subject: [ALSA] pcm_native: lockdep warning when launching jack When launching 'jackd -d alsa', lockdep issues the following warning: [39701.405086] ============================================= [39701.405093] [ INFO: possible recursive locking detected ] [39701.405107] 2.6.21-rc5-mm4 #2 [39701.405109] --------------------------------------------- [39701.405112] jackd/17366 is trying to acquire lock: [39701.405114] (&substream->self_group.lock){....}, at: [] snd_pcm_action_group+0x90/0x240 [39701.405131] [39701.405131] but task is already holding lock: [39701.405134] (&substream->self_group.lock){....}, at: [] snd_pcm_action_lock_irq+0x3f/0xb0 [39701.405141] [39701.405142] other info that might help us debug this: [39701.405145] 3 locks held by jackd/17366: [39701.405147] #0: (snd_pcm_link_rwlock){....}, at: [] snd_pcm_action_lock_irq+0x27/0xb0 [39701.405155] #1: (&substream->group->lock){....}, at: [] snd_pcm_action_lock_irq+0x38/0xb0 [39701.405163] #2: (&substream->self_group.lock){....}, at: [] snd_pcm_action_lock_irq+0x3f/0xb0 [39701.405171] [39701.405171] stack backtrace: [39701.405174] [] show_trace_log_lvl+0x1a/0x30 [39701.405179] [] show_trace+0x12/0x20 [39701.405183] [] dump_stack+0x16/0x20 [39701.405187] [] __lock_acquire+0xbd0/0x1040 [39701.405193] [] lock_acquire+0x70/0x90 [39701.405197] [] _spin_lock+0x36/0x50 [39701.405203] [] snd_pcm_action_group+0x90/0x240 [39701.405207] [] snd_pcm_action_lock_irq+0x53/0xb0 [39701.405211] [] snd_pcm_common_ioctl1+0x35f/0xfb0 [39701.405215] [] snd_pcm_playback_ioctl1+0x34/0x420 [39701.405219] [] snd_pcm_playback_ioctl+0x43/0x50 [39701.405223] [] do_ioctl+0x28/0x80 [39701.405229] [] vfs_ioctl+0x57/0x290 [39701.405233] [] sys_ioctl+0x39/0x60 [39701.405237] [] sysenter_past_esp+0x5d/0x99 [39701.405240] ======================= The attached lockdep annotation silences the warning. Signed-off-by: Frederik Deweerdt Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 42a039c..a96733a 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -718,7 +718,8 @@ static int snd_pcm_action_group(struct action_ops *ops, snd_pcm_group_for_each_entry(s, substream) { if (do_lock && s != substream) - spin_lock(&s->self_group.lock); + spin_lock_nested(&s->self_group.lock, + SINGLE_DEPTH_NESTING); res = ops->pre_action(s, state); if (res < 0) goto _unlock; -- cgit v0.10.2 From c4116ae717d6456884232642bae806125d39f1d3 Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Thu, 5 Apr 2007 17:07:30 +0200 Subject: [ALSA] Fix misc bugs in i2c/others/ak4114.c * correct register for 'IEC958 Non-PCM Bitstream', 'IEC958 DTS Bitstream' to use AK4114_REG_RCS0 * correct check for control name: if (strstr(kctl->id.name, 'Playback')) * correct check: if (!chip->init) in snd_ak4114_external_rate * added PCM control 'IEC958 PPL Lock Status' Signed-off-by: Pavel Hofman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h index 54a5a42..d647dae 100644 --- a/include/sound/ak4114.h +++ b/include/sound/ak4114.h @@ -158,7 +158,7 @@ #define AK4114_CHECK_NO_STAT (1<<0) /* no statistics */ #define AK4114_CHECK_NO_RATE (1<<1) /* no rate check */ -#define AK4114_CONTROLS 14 +#define AK4114_CONTROLS 15 typedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data); typedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr); diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c index 8f7c42c..1efb973 100644 --- a/sound/i2c/other/ak4114.c +++ b/sound/i2c/other/ak4114.c @@ -435,7 +435,7 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4114_in_bit_info, .get = snd_ak4114_in_bit_get, - .private_value = (6<<8) | AK4114_REG_RCS1, + .private_value = (6<<8) | AK4114_REG_RCS0, }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -443,7 +443,15 @@ static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = { .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = snd_ak4114_in_bit_info, .get = snd_ak4114_in_bit_get, - .private_value = (3<<8) | AK4114_REG_RCS1, + .private_value = (3<<8) | AK4114_REG_RCS0, +}, +{ + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "IEC958 PPL Lock Status", + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_ak4114_in_bit_info, + .get = snd_ak4114_in_bit_get, + .private_value = (1<<31) | (4<<8) | AK4114_REG_RCS0, } }; @@ -462,7 +470,7 @@ int snd_ak4114_build(struct ak4114 *ak4114, kctl = snd_ctl_new1(&snd_ak4114_iec958_controls[idx], ak4114); if (kctl == NULL) return -ENOMEM; - if (!strstr(kctl->id.name, "Playback")) { + if (strstr(kctl->id.name, "Playback")) { if (ply_substream == NULL) { snd_ctl_free_one(kctl); ak4114->kctls[idx] = NULL; @@ -526,6 +534,9 @@ static void ak4114_notify(struct ak4114 *ak4114, if (c0 & AK4114_DTSCD) snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, &ak4114->kctls[13]->id); + if (c0 & AK4114_UNLCK) + snd_ctl_notify(ak4114->card, SNDRV_CTL_EVENT_MASK_VALUE, + &ak4114->kctls[14]->id); } int snd_ak4114_external_rate(struct ak4114 *ak4114) @@ -587,7 +598,7 @@ static void ak4114_stats(struct work_struct *work) { struct ak4114 *chip = container_of(work, struct ak4114, work.work); - if (chip->init) + if (!chip->init) snd_ak4114_check_rate_and_errors(chip, 0); schedule_delayed_work(&chip->work, HZ / 10); -- cgit v0.10.2 From fdd4bb49ec3f401379875990fcece611c623e32f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 5 Apr 2007 17:08:57 +0200 Subject: [ALSA] ice1724 - call snd_ak4114_build() in juli Call snd_ak4114_build() in juli support code to build proper mixer elements for SPDIF inputs. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index dd0da95..3d8e74e 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -138,7 +138,16 @@ static struct snd_akm4xxx akm_juli_dac __devinitdata = { static int __devinit juli_add_controls(struct snd_ice1712 *ice) { - return snd_ice1712_akm4xxx_build_controls(ice); + int err; + err = snd_ice1712_akm4xxx_build_controls(ice); + if (err < 0) + return err; + /* only capture SPDIF over AK4114 */ + err = snd_ak4114_build(ice->spec.juli.ak4114, NULL, + ice->pcm_pro->streams[SNDRV_PCM_STREAM_CAPTURE].substream); + if (err < 0) + return err; + return 0; } /* -- cgit v0.10.2 From f06934bd3cf773c297683d1345bf61c7807d7e75 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 10 Apr 2007 11:15:34 +0200 Subject: [ALSA] ice1724 - Add comments for naming of PCM streams Added some comments regarding naming of PCM streams on vt172x chip. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 0666cbc..6a29bcf 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -2345,6 +2345,14 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, } c = &no_matched; __found: + /* + * VT1724 has separate DMAs for the analog and the SPDIF streams while + * ICE1712 has only one for both (mixed up). + * + * Confusingly the analog PCM is named "professional" here because it + * was called so in ice1712 driver, and vt1724 driver is derived from + * ice1712 driver. + */ if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) { snd_card_free(card); -- cgit v0.10.2 From 7d4b4380d37025f0b13ae951e0cb2ff7184dc5bb Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Tue, 10 Apr 2007 11:39:58 +0200 Subject: [ALSA] ice1724 - Functioning support for Prodigy 192 Fixes: -------- * correct card specific ice1724 initialization * working IEC958 output of the card * renamed capture controls New features: ------------------ * analog input switch (line-in/mic) * optional ak4114 based MI/ODI/O card detection & support: IEC958 input, digital input switch (toslink/coax) Unresolved issues ----------------------- * Analog and digital input enums are listed on playback panel of alsamixer, I do not know how to push them onto the capture one. Signed-off-by: Pavel Hofman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index c3d9fea..6ac486d 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h @@ -397,6 +397,9 @@ struct snd_ice1712 { struct ak4114 *ak4114; unsigned int analog: 1; } juli; + struct { + struct ak4114 *ak4114; + } prodigy192; } spec; }; diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index 9aad6b3..ae08a07 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -2,6 +2,30 @@ * ALSA driver for ICEnsemble VT1724 (Envy24HT) * * Lowlevel functions for AudioTrak Prodigy 192 cards + * Supported IEC958 input from optional MI/ODI/O add-on card. + * + * Specifics (SW, HW): + * ------------------- + * * 49.5MHz crystal + * * SPDIF-OUT on the card: + * - coax (through isolation transformer)/toslink supplied by + * 74HC04 gates - 3 in parallel + * - output switched between on-board CD drive dig-out connector + * and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled + * by GPIO20 (0 = CD dig-out, 1 = SPDTX) + * * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax + * + * * MI/ODI/O card: AK4114 based, used for iec958 input only + * - toslink input -> RX0 + * - coax input -> RX1 + * - 4wire protocol: + * AK4114 ICE1724 + * ------------------------------ + * CDTO (pin 32) -- GPIO11 pin 86 + * CDTI (pin 33) -- GPIO10 pin 77 + * CCLK (pin 34) -- GPIO9 pin 76 + * CSN (pin 35) -- GPIO8 pin 75 + * - output data Mode 7 (24bit, I2S, slave) * * Copyright (c) 2003 Takashi Iwai * Copyright (c) 2003 Dimitromanolakis Apostolos @@ -356,6 +380,47 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } #endif +static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[2] = { "Line In", "Mic" }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + + return 0; +} + + +static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char val; + + val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); + ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1; + return 0; +} + +static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char new, old; + int change; + old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); + new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80); + change = (new != old); + if (change) + stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); + return change; +} static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); @@ -406,7 +471,7 @@ static struct snd_kcontrol_new stac_controls[] __devinitdata = { }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Switch", + .name = "ADC Capture Switch", .count = 1, .info = stac9460_adc_mute_info, .get = stac9460_adc_mute_get, @@ -417,13 +482,21 @@ static struct snd_kcontrol_new stac_controls[] __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "ADC Volume", + .name = "ADC Capture Volume", .count = 1, .info = stac9460_adc_vol_info, .get = stac9460_adc_vol_get, .put = stac9460_adc_vol_put, .tlv = { .p = db_scale_adc } }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Analog Capture Input", + .info = stac9460_mic_sw_info, + .get = stac9460_mic_sw_get, + .put = stac9460_mic_sw_put, + + }, #if 0 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -456,19 +529,258 @@ static struct snd_kcontrol_new stac_controls[] __devinitdata = { #endif }; + +/* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */ +/* CDTO (pin 32) -- GPIO11 pin 86 + * CDTI (pin 33) -- GPIO10 pin 77 + * CCLK (pin 34) -- GPIO9 pin 76 + * CSN (pin 35) -- GPIO8 pin 75 + */ +#define AK4114_ADDR 0x00 /* C1-C0: Chip Address + * (According to datasheet fixed to “00”) + */ + +/* + * 4wire ak4114 protocol - writing data + */ +static void write_data(struct snd_ice1712 *ice, unsigned int gpio, + unsigned int data, int idx) +{ + for (; idx >= 0; idx--) { + /* drop clock */ + gpio &= ~VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + /* set data */ + if (data & (1 << idx)) + gpio |= VT1724_PRODIGY192_CDOUT; + else + gpio &= ~VT1724_PRODIGY192_CDOUT; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + /* raise clock */ + gpio |= VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + } +} + +/* + * 4wire ak4114 protocol - reading data + */ +static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, + int idx) +{ + unsigned char data = 0; + + for (; idx >= 0; idx--) { + /* drop clock */ + gpio &= ~VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + /* read data */ + if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN) + data |= (1 << idx); + udelay(1); + /* raise clock */ + gpio |= VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + } + return data; +} +/* + * 4wire ak4114 protocol - starting sequence + */ +static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice) +{ + unsigned int tmp; + + snd_ice1712_save_gpio_status(ice); + tmp = snd_ice1712_gpio_read(ice); + + tmp |= VT1724_PRODIGY192_CCLK; /* high at init */ + tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */ + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + return tmp; +} + +/* + * 4wire ak4114 protocol - final sequence + */ +static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) +{ + tmp |= VT1724_PRODIGY192_CS; /* raise chip select */ + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + snd_ice1712_restore_gpio_status(ice); +} + +/* + * Write data to addr register of ak4114 + */ +static void prodigy192_ak4114_write(void *private_data, unsigned char addr, + unsigned char data) +{ + struct snd_ice1712 *ice = private_data; + unsigned int tmp, addrdata; + tmp = prodigy192_4wire_start(ice); + addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); + addrdata = (addrdata << 8) | data; + write_data(ice, tmp, addrdata, 15); + prodigy192_4wire_finish(ice, tmp); +} + +/* + * Read data from addr register of ak4114 + */ +static unsigned char prodigy192_ak4114_read(void *private_data, + unsigned char addr) +{ + struct snd_ice1712 *ice = private_data; + unsigned int tmp; + unsigned char data; + + tmp = prodigy192_4wire_start(ice); + write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); + data = read_data(ice, tmp, 7); + prodigy192_4wire_finish(ice, tmp); + return data; +} + + +static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[2] = { "Toslink", "Coax" }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + + +static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char val; + + val = prodigy192_ak4114_read(ice, AK4114_REG_IO1); + /* AK4114_IPS0 bit = 0 -> RX0 = Toslink + * AK4114_IPS0 bit = 1 -> RX1 = Coax + */ + ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0; + return 0; +} + +static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char new, old, itemvalue; + int change; + + old = prodigy192_ak4114_read(ice, AK4114_REG_IO1); + /* AK4114_IPS0 could be any bit */ + itemvalue = (ucontrol->value.enumerated.item[0]) ? 0xff : 0x00; + + new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0); + change = (new != old); + if (change) + prodigy192_ak4114_write(ice, AK4114_REG_IO1, new); + return change; +} + + +static const struct snd_kcontrol_new ak4114_controls[] __devinitdata = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "MIODIO IEC958 Capture Input", + .info = ak4114_input_sw_info, + .get = ak4114_input_sw_get, + .put = ak4114_input_sw_put, + + } +}; + + +static int prodigy192_ak4114_init(struct snd_ice1712 *ice) +{ + static const unsigned char ak4114_init_vals[] = { + AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, + AK4114_DIF_I24I2S, /* ice1724 expects I2S and provides clock */ + AK4114_TX1E, + AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */ + 0, + 0 + }; + static const unsigned char ak4114_init_txcsb[] = { + 0x41, 0x02, 0x2c, 0x00, 0x00 + }; + + return snd_ak4114_create(ice->card, + prodigy192_ak4114_read, + prodigy192_ak4114_write, + ak4114_init_vals, ak4114_init_txcsb, + ice, &ice->spec.prodigy192.ak4114); +} + static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) { unsigned int i; int err; for (i = 0; i < ARRAY_SIZE(stac_controls); i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&stac_controls[i], ice)); + err = snd_ctl_add(ice->card, + snd_ctl_new1(&stac_controls[i], ice)); + if (err < 0) + return err; + } + if (ice->spec.prodigy192.ak4114) { + /* ak4114 is connected */ + for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) { + err = snd_ctl_add(ice->card, + snd_ctl_new1(&ak4114_controls[i], + ice)); + if (err < 0) + return err; + } + err = snd_ak4114_build(ice->spec.prodigy192.ak4114, + NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */ + ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); if (err < 0) return err; } return 0; } +/* + * check for presence of MI/ODI/O add-on card with digital inputs + */ +static int prodigy192_miodio_exists(struct snd_ice1712 *ice) +{ + + unsigned char orig_value; + const unsigned char test_data = 0xd1; /* random value */ + unsigned char addr = AK4114_REG_INT0_MASK; /* random SAFE address */ + int exists = 0; + + orig_value = prodigy192_ak4114_read(ice, addr); + prodigy192_ak4114_write(ice, addr, test_data); + if (prodigy192_ak4114_read(ice, addr) == test_data) { + /* ak4114 seems to communicate, apparently exists */ + /* writing back original value */ + prodigy192_ak4114_write(ice, addr, orig_value); + exists = 1; + } + return exists; +} /* * initialize the chip @@ -487,16 +799,30 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) (unsigned short)-1 }; const unsigned short *p; + int err = 0; /* prodigy 192 */ ice->num_total_dacs = 6; ice->num_total_adcs = 2; + ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */ /* initialize codec */ p = stac_inits_prodigy; for (; *p != (unsigned short)-1; p += 2) stac9460_put(ice, p[0], p[1]); + /* MI/ODI/O add on card with AK4114 */ + if (prodigy192_miodio_exists(ice)) { + err = prodigy192_ak4114_init(ice); + /* from this moment if err = 0 then + * ice->spec.prodigy192.ak4114 should not be null + */ + snd_printdd("AK4114 initialized with status %d\n", err); + } else + snd_printdd("AK4114 not found\n"); + if (err < 0) + return err; + return 0; } @@ -507,19 +833,25 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) */ static unsigned char prodigy71_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC, 4DACs */ + [ICE_EEP2_SYSCONF] = 0x6a, /* 49MHz crystal, mpu401, + * spdif-in+ 1 stereo ADC, + * 3 stereo DACs + */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, + [ICE_EEP2_GPIO_DIR1] = ~(VT1724_PRODIGY192_CDIN >> 8) , [ICE_EEP2_GPIO_DIR2] = 0xbf, [ICE_EEP2_GPIO_MASK] = 0x00, [ICE_EEP2_GPIO_MASK1] = 0x00, [ICE_EEP2_GPIO_MASK2] = 0x00, [ICE_EEP2_GPIO_STATE] = 0x00, [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, + [ICE_EEP2_GPIO_STATE2] = 0x10, /* GPIO20: 0 = CD drive dig. input + * passthrough, + * 1 = SPDIF-OUT from ice1724 + */ }; diff --git a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h index 94c824e..16a53b4 100644 --- a/sound/pci/ice1712/prodigy192.h +++ b/sound/pci/ice1712/prodigy192.h @@ -5,6 +5,14 @@ #define PRODIGY192_STAC9460_ADDR 0x54 #define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */ +/* + * AudioTrak Prodigy192 GPIO definitions for MI/ODI/O card with + * AK4114 (SPDIF-IN) + */ +#define VT1724_PRODIGY192_CS (1 << 8) /* GPIO8, pin 75 */ +#define VT1724_PRODIGY192_CCLK (1 << 9) /* GPIO9, pin 76 */ +#define VT1724_PRODIGY192_CDOUT (1 << 10) /* GPIO10, pin 77 */ +#define VT1724_PRODIGY192_CDIN (1 << 11) /* GPIO11, pin 86 */ extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; -- cgit v0.10.2 From bc9f98a9815c452a74e5eb9cbd2ed61b337fdcd2 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Thu, 12 Apr 2007 13:06:07 +0200 Subject: [ALSA] hda-codec - Add ALC662 support - Add ALC662 support - Fixed no sound for [0x1631, 0xc017, 'PB V7900', ALC260_WILL] - Fixed no sound for [0x161f, 0x2057, 'Replacer 672V', ALC260_REPLACER_672V] - Add SKU ID for auto mode Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d3f7a3d..5d7f619 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -74,6 +74,8 @@ enum { ALC260_HP_3013, ALC260_FUJITSU_S702X, ALC260_ACER, + ALC260_WILL, + ALC260_REPLACER_672V, #ifdef CONFIG_SND_DEBUG ALC260_TEST, #endif @@ -119,6 +121,17 @@ enum { ALC861VD_MODEL_LAST, }; +/* ALC662 models */ +enum { + ALC662_3ST_2ch_DIG, + ALC662_3ST_6ch_DIG, + ALC662_3ST_6ch, + ALC662_5ST_DIG, + ALC662_LENOVO_101E, + ALC662_AUTO, + ALC662_MODEL_LAST, +}; + /* ALC882 models */ enum { ALC882_3ST_DIG, @@ -141,6 +154,7 @@ enum { ALC883_ACER, ALC883_MEDION, ALC883_LAPTOP_EAPD, + ALC883_LENOVO_101E_2ch, ALC883_AUTO, ALC883_MODEL_LAST, }; @@ -604,6 +618,68 @@ static void setup_preset(struct alc_spec *spec, spec->init_hook = preset->init_hook; } +/* Enable GPIO mask and set output */ +static struct hda_verb alc_gpio1_init_verbs[] = { + {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, + { } +}; + +static struct hda_verb alc_gpio2_init_verbs[] = { + {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, + { } +}; + +/* 32-bit subsystem ID for BIOS loading in HD Audio codec. + * 31 ~ 16 : Manufacture ID + * 15 ~ 8 : SKU ID + * 7 ~ 0 : Assembly ID + * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 + */ +static void alc_subsystem_id(struct hda_codec *codec, + unsigned int porta, unsigned int porte, + unsigned int portd) +{ + unsigned int ass, tmp; + + ass = codec->subsystem_id; + if (!(ass & 1)) + return; + + /* Override */ + tmp = (ass & 0x38) >> 3; /* external Amp control */ + switch (tmp) { + case 1: + snd_hda_sequence_write(codec, alc_gpio1_init_verbs); + break; + case 3: + snd_hda_sequence_write(codec, alc_gpio2_init_verbs); + break; + case 5: + case 6: + if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */ + hda_nid_t port = 0; + tmp = (ass & 0x1800) >> 11; + switch (tmp) { + case 0: port = porta; break; + case 1: port = porte; break; + case 2: port = portd; break; + } + if (port) + snd_hda_codec_write(codec, port, 0, + AC_VERB_SET_EAPD_BTLENABLE, + 2); + } + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, + (tmp == 5 ? 0x3040 : 0x3050)); + break; + } +} + /* * ALC880 3-stack model * @@ -1547,22 +1623,8 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = { }; /* Enable GPIO mask and set output */ -static struct hda_verb alc880_gpio1_init_verbs[] = { - {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, - - { } -}; - -/* Enable GPIO mask and set output */ -static struct hda_verb alc880_gpio2_init_verbs[] = { - {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, - - { } -}; +#define alc880_gpio1_init_verbs alc_gpio1_init_verbs +#define alc880_gpio2_init_verbs alc_gpio2_init_verbs /* Clevo m520g init */ static struct hda_verb alc880_pin_clevo_init_verbs[] = { @@ -2980,7 +3042,8 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int i; - + + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); @@ -3361,6 +3424,42 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { { } /* end */ }; +/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, + * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. + */ +static struct snd_kcontrol_new alc260_will_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), + ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), + HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), + ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), + { } /* end */ +}; + +/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, + * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. + */ +static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), + ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), + HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), + ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), + { } /* end */ +}; + /* capture mixer elements */ static struct snd_kcontrol_new alc260_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), @@ -3731,6 +3830,55 @@ static struct hda_verb alc260_acer_init_verbs[] = { { } }; +static struct hda_verb alc260_will_verbs[] = { + {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, + {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, + {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, + {} +}; + +static struct hda_verb alc260_replacer_672v_verbs[] = { + {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, + {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, + {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, + + {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, + + {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +/* toggle speaker-output according to the hp-jack state */ +static void alc260_replacer_672v_automute(struct hda_codec *codec) +{ + unsigned int present; + + /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ + present = snd_hda_codec_read(codec, 0x0f, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + if (present) { + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1); + snd_hda_codec_write(codec, 0x0f, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); + } else { + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); + snd_hda_codec_write(codec, 0x0f, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + } +} + +static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc260_replacer_672v_automute(codec); +} + /* Test configuration for debugging, modelled after the ALC880 test * configuration. */ @@ -4053,6 +4201,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; hda_nid_t nid; + alc_subsystem_id(codec, 0x10, 0x15, 0x0f); nid = spec->autocfg.line_out_pins[0]; if (nid) alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); @@ -4189,6 +4338,8 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { [ALC260_HP_3013] = "hp-3013", [ALC260_FUJITSU_S702X] = "fujitsu", [ALC260_ACER] = "acer", + [ALC260_WILL] = "will", + [ALC260_REPLACER_672V] = "replacer", #ifdef CONFIG_SND_DEBUG [ALC260_TEST] = "test", #endif @@ -4212,6 +4363,8 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), + SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), + SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), {} }; @@ -4282,6 +4435,34 @@ static struct alc_config_preset alc260_presets[] = { .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), .input_mux = alc260_acer_capture_sources, }, + [ALC260_WILL] = { + .mixers = { alc260_will_mixer, + alc260_capture_mixer }, + .init_verbs = { alc260_init_verbs, alc260_will_verbs }, + .num_dacs = ARRAY_SIZE(alc260_dac_nids), + .dac_nids = alc260_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), + .adc_nids = alc260_adc_nids, + .dig_out_nid = ALC260_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc260_modes), + .channel_mode = alc260_modes, + .input_mux = &alc260_capture_source, + }, + [ALC260_REPLACER_672V] = { + .mixers = { alc260_replacer_672v_mixer, + alc260_capture_mixer }, + .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, + .num_dacs = ARRAY_SIZE(alc260_dac_nids), + .dac_nids = alc260_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), + .adc_nids = alc260_adc_nids, + .dig_out_nid = ALC260_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc260_modes), + .channel_mode = alc260_modes, + .input_mux = &alc260_capture_source, + .unsol_event = alc260_replacer_672v_unsol_event, + .init_hook = alc260_replacer_672v_automute, + }, #ifdef CONFIG_SND_DEBUG [ALC260_TEST] = { .mixers = { alc260_test_mixer, @@ -4881,6 +5062,7 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; if (nid) @@ -5057,6 +5239,15 @@ static struct hda_input_mux alc883_capture_source = { { "CD", 0x4 }, }, }; + +static struct hda_input_mux alc883_lenovo_101e_capture_source = { + .num_items = 2, + .items = { + { "Mic", 0x1 }, + { "Line", 0x2 }, + }, +}; + #define alc883_mux_enum_info alc_mux_enum_info #define alc883_mux_enum_get alc_mux_enum_get @@ -5364,6 +5555,29 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc883_mux_enum_info, + .get = alc883_mux_enum_get, + .put = alc883_mux_enum_put, + }, + { } /* end */ +}; + static struct snd_kcontrol_new alc883_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -5471,6 +5685,13 @@ static struct hda_verb alc883_tagra_verbs[] = { { } /* end */ }; +static struct hda_verb alc883_lenovo_101e_verbs[] = { + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, + { } /* end */ +}; + /* toggle speaker-output according to the hp-jack state */ static void alc883_tagra_automute(struct hda_codec *codec) { @@ -5491,6 +5712,45 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) alc883_tagra_automute(codec); } +static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x14, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); +} + +static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); +} + +static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc883_lenovo_101e_all_automute(codec); + if ((res >> 26) == ALC880_FRONT_EVENT) + alc883_lenovo_101e_ispeaker_automute(codec); +} + /* * generic initialization of ADC, input mixers and output mixers */ @@ -5596,6 +5856,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_ACER] = "acer", [ALC883_MEDION] = "medion", [ALC883_LAPTOP_EAPD] = "laptop-eapd", + [ALC883_LENOVO_101E_2ch] = "lenovo-101e", [ALC883_AUTO] = "auto", }; @@ -5621,6 +5882,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), + SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch), {} }; @@ -5761,6 +6023,19 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, }, + [ALC883_LENOVO_101E_2ch] = { + .mixers = { alc883_lenovo_101e_2ch_mixer}, + .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .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_lenovo_101e_capture_source, + .unsol_event = alc883_lenovo_101e_unsol_event, + .init_hook = alc883_lenovo_101e_all_automute, + }, }; @@ -5793,6 +6068,7 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; if (nid) @@ -5845,8 +6121,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec) else if (err > 0) /* hack - override the init verbs */ spec->init_verbs[0] = alc883_auto_init_verbs; - spec->mixers[spec->num_mixers] = alc883_capture_mixer; - spec->num_mixers++; + spec->mixers[spec->num_mixers] = alc883_capture_mixer; + spec->num_mixers++; return err; } @@ -7533,9 +7809,6 @@ static void alc861_toshiba_automute(struct hda_codec *codec) static void alc861_toshiba_unsol_event(struct hda_codec *codec, unsigned int res) { - /* Looks like the unsol event is incompatible with the standard - * definition. 6bit tag is placed at 26 bit! - */ if ((res >> 26) == ALC880_HP_EVENT) alc861_toshiba_automute(codec); } @@ -7729,6 +8002,7 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; if (nid) @@ -8423,6 +8697,7 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; if (nid) @@ -8689,16 +8964,857 @@ static int patch_alc861vd(struct hda_codec *codec) } /* + * ALC662 support + * + * ALC662 is almost identical with ALC880 but has cleaner and more flexible + * configuration. Each pin widget can choose any input DACs and a mixer. + * Each ADC is connected from a mixer of all inputs. This makes possible + * 6-channel independent captures. + * + * In addition, an independent DAC for the multi-playback (not used in this + * driver yet). + */ +#define ALC662_DIGOUT_NID 0x06 +#define ALC662_DIGIN_NID 0x0a + +static hda_nid_t alc662_dac_nids[4] = { + /* front, rear, clfe, rear_surr */ + 0x02, 0x03, 0x04 +}; + +static hda_nid_t alc662_adc_nids[1] = { + /* ADC1-2 */ + 0x09, +}; +/* input MUX */ +/* FIXME: should be a matrix-type input source selection */ + +static struct hda_input_mux alc662_capture_source = { + .num_items = 4, + .items = { + { "Mic", 0x0 }, + { "Front Mic", 0x1 }, + { "Line", 0x2 }, + { "CD", 0x4 }, + }, +}; + +static struct hda_input_mux alc662_lenovo_101e_capture_source = { + .num_items = 2, + .items = { + { "Mic", 0x1 }, + { "Line", 0x2 }, + }, +}; +#define alc662_mux_enum_info alc_mux_enum_info +#define alc662_mux_enum_get alc_mux_enum_get + +static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + const struct hda_input_mux *imux = spec->input_mux; + unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; + hda_nid_t nid = capture_mixers[adc_idx]; + unsigned int *cur_val = &spec->cur_mux[adc_idx]; + unsigned int i, idx; + + idx = ucontrol->value.enumerated.item[0]; + if (idx >= imux->num_items) + idx = imux->num_items - 1; + if (*cur_val == idx && ! codec->in_resume) + return 0; + for (i = 0; i < imux->num_items; i++) { + unsigned int v = (i == idx) ? 0x7000 : 0x7080; + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + v | (imux->items[i].index << 8)); + } + *cur_val = idx; + return 1; +} +/* + * 2ch mode + */ +static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { + { 2, NULL } +}; + +/* + * 2ch mode + */ +static struct hda_verb alc662_3ST_ch2_init[] = { + { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, + { } /* end */ +}; + +/* + * 6ch mode + */ +static struct hda_verb alc662_3ST_ch6_init[] = { + { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, + { } /* end */ +}; + +static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { + { 2, alc662_3ST_ch2_init }, + { 6, alc662_3ST_ch6_init }, +}; + +/* + * 2ch mode + */ +static struct hda_verb alc662_sixstack_ch6_init[] = { + { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, + { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, + { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { } /* end */ +}; + +/* + * 6ch mode + */ +static struct hda_verb alc662_sixstack_ch8_init[] = { + { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { } /* end */ +}; + +static struct hda_channel_mode alc662_5stack_modes[2] = { + { 2, alc662_sixstack_ch6_init }, + { 6, alc662_sixstack_ch8_init }, +}; + +/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 + * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b + */ + +static struct snd_kcontrol_new alc662_base_mixer[] = { + /* output mixer control */ + HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + + /*Input mixer control */ + HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), + + /* Capture mixer control */ + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .count = 1, + .info = alc_mux_enum_info, + .get = alc_mux_enum_get, + .put = alc_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc662_mux_enum_info, + .get = alc662_mux_enum_get, + .put = alc662_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc662_mux_enum_info, + .get = alc662_mux_enum_get, + .put = alc662_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), + HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc662_mux_enum_info, + .get = alc662_mux_enum_get, + .put = alc662_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_chmode_mixer[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Channel Mode", + .info = alc_ch_mode_info, + .get = alc_ch_mode_get, + .put = alc_ch_mode_put, + }, + { } /* end */ +}; + +static struct hda_verb alc662_init_verbs[] = { + /* ADC: mute amp left and right */ + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* Front mixer: unmute input/output amp left and right (volume = 0) */ + + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + /* Front Pin: output 0 (0x0c) */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* Rear Pin: output 1 (0x0d) */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* CLFE Pin: output 2 (0x0e) */ + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* Mic (rear) pin: input vref at 80% */ + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Front Mic pin: input vref at 80% */ + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Line In pin: input */ + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Line-2 In: Headphone output (output 0 - 0x0c) */ + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* CD pin widget for input */ + {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + + /* FIXME: use matrix-type input source selection */ + /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ + /* Input mixer */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + { } +}; + +static struct hda_verb alc662_sue_init_verbs[] = { + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, + {} +}; + +/* + * generic initialization of ADC, input mixers and output mixers + */ +static struct hda_verb alc662_auto_init_verbs[] = { + /* + * Unmute ADC and set the default input to mic-in + */ + {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + + /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + * mixer widget + * Note: PASD motherboards uses the Line In 2 as the input for front + * panel mic (mic 2) + */ + /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + /* + * Set up output mixers (0x0c - 0x0f) + */ + /* set vol=0 to output mixers */ + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + + /* set up input amps for analog loopback */ + /* Amp Indices: DAC = 0, mixer = 1 */ + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + + /* FIXME: use matrix-type input source selection */ + /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ + /* Input mixer */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/ + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + { } +}; + +/* capture mixer elements */ +static struct snd_kcontrol_new alc662_capture_mixer[] = { + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* The multiple "Capture Source" controls confuse alsamixer + * So call somewhat different.. + * FIXME: the controls appear in the "playback" view! + */ + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc882_mux_enum_info, + .get = alc882_mux_enum_get, + .put = alc882_mux_enum_put, + }, + { } /* end */ +}; + +static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x14, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); +} + +static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); + snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, + 0x80, present ? 0x80 : 0); +} + +static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc662_lenovo_101e_all_automute(codec); + if ((res >> 26) == ALC880_FRONT_EVENT) + alc662_lenovo_101e_ispeaker_automute(codec); +} + + +/* pcm configuration: identiacal with ALC880 */ +#define alc662_pcm_analog_playback alc880_pcm_analog_playback +#define alc662_pcm_analog_capture alc880_pcm_analog_capture +#define alc662_pcm_digital_playback alc880_pcm_digital_playback +#define alc662_pcm_digital_capture alc880_pcm_digital_capture + +/* + * configuration and preset + */ +static const char *alc662_models[ALC662_MODEL_LAST] = { + [ALC662_3ST_2ch_DIG] = "3stack-dig", + [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", + [ALC662_3ST_6ch] = "3stack-6ch", + [ALC662_5ST_DIG] = "6stack-dig", + [ALC662_LENOVO_101E] = "lenovo-101e", + [ALC662_AUTO] = "auto", +}; + +static struct snd_pci_quirk alc662_cfg_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), + {} +}; + +static struct alc_config_preset alc662_presets[] = { + [ALC662_3ST_2ch_DIG] = { + .mixers = { alc662_3ST_2ch_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .dig_in_nid = ALC662_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_capture_source, + }, + [ALC662_3ST_6ch_DIG] = { + .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .dig_in_nid = ALC662_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), + .channel_mode = alc662_3ST_6ch_modes, + .need_dac_fix = 1, + .input_mux = &alc662_capture_source, + }, + [ALC662_3ST_6ch] = { + .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), + .channel_mode = alc662_3ST_6ch_modes, + .need_dac_fix = 1, + .input_mux = &alc662_capture_source, + }, + [ALC662_5ST_DIG] = { + .mixers = { alc662_base_mixer, alc662_chmode_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .dig_in_nid = ALC662_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), + .channel_mode = alc662_5stack_modes, + .input_mux = &alc662_capture_source, + }, + [ALC662_LENOVO_101E] = { + .mixers = { alc662_lenovo_101e_mixer }, + .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_lenovo_101e_capture_source, + .unsol_event = alc662_lenovo_101e_unsol_event, + .init_hook = alc662_lenovo_101e_all_automute, + }, + +}; + + +/* + * BIOS auto configuration + */ + +/* add playback controls from the parsed DAC table */ +static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) +{ + char name[32]; + static const char *chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; + hda_nid_t nid; + int i, err; + + for (i = 0; i < cfg->line_outs; i++) { + if (!spec->multiout.dac_nids[i]) + continue; + nid = alc880_idx_to_dac(i); + if (i == 2) { + /* Center/LFE */ + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Center Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); + if (err < 0) + return err; + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); + if (err < 0) + return err; + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT)); + if (err < 0) + return err; + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT)); + if (err < 0) + return err; + } else { + sprintf(name, "%s Playback Volume", chname[i]); + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + sprintf(name, "%s Playback Switch", chname[i]); + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); + if (err < 0) + return err; + } + } + return 0; +} + +/* add playback controls for speaker and HP outputs */ +static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, + const char *pfx) +{ + hda_nid_t nid; + int err; + char name[32]; + + if (!pin) + return 0; + + if (alc880_is_fixed_pin(pin)) { + nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); + /* printk("DAC nid=%x\n",nid); */ + /* specify the DAC as the extra output */ + if (!spec->multiout.hp_nid) + spec->multiout.hp_nid = nid; + else + spec->multiout.extra_out_nid[0] = nid; + /* control HP volume/switch on the output mixer amp */ + nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); + sprintf(name, "%s Playback Volume", pfx); + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + sprintf(name, "%s Playback Switch", pfx); + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); + if (err < 0) + return err; + } else if (alc880_is_multi_pin(pin)) { + /* set manual connection */ + /* we have only a switch on HP-out PIN */ + sprintf(name, "%s Playback Switch", pfx); + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + } + return 0; +} + +/* create playback/capture controls for input pins */ +static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) +{ + struct hda_input_mux *imux = &spec->private_imux; + int i, err, idx; + + for (i = 0; i < AUTO_PIN_LAST; i++) { + if (alc880_is_input_pin(cfg->input_pins[i])) { + idx = alc880_input_pin_idx(cfg->input_pins[i]); + err = new_analog_input(spec, cfg->input_pins[i], + auto_pin_cfg_labels[i], + idx, 0x0b); + if (err < 0) + return err; + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; + imux->items[imux->num_items].index = + alc880_input_pin_idx(cfg->input_pins[i]); + imux->num_items++; + } + } + return 0; +} + +static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, + hda_nid_t nid, int pin_type, + int dac_idx) +{ + /* set as output */ + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + /* need the manual connection? */ + if (alc880_is_multi_pin(nid)) { + struct alc_spec *spec = codec->spec; + int idx = alc880_multi_pin_idx(nid); + snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, + AC_VERB_SET_CONNECT_SEL, + alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); + } +} + +static void alc662_auto_init_multi_out(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i <= HDA_SIDE; i++) { + hda_nid_t nid = spec->autocfg.line_out_pins[i]; + if (nid) + alc662_auto_set_output_and_unmute(codec, nid, PIN_OUT, + i); + } +} + +static void alc662_auto_init_hp_out(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t pin; + + pin = spec->autocfg.hp_pins[0]; + if (pin) /* connect to front */ + /* use dac 0 */ + alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); +} + +#define alc662_is_input_pin(nid) alc880_is_input_pin(nid) +#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID + +static void alc662_auto_init_analog_input(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i < AUTO_PIN_LAST; i++) { + hda_nid_t nid = spec->autocfg.input_pins[i]; + if (alc662_is_input_pin(nid)) { + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + (i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN)); + if (nid != ALC662_PIN_CD_NID) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_MUTE); + } + } +} + +static int alc662_parse_auto_config(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int err; + static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; + + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc662_ignore); + if (err < 0) + return err; + if (!spec->autocfg.line_outs) + return 0; /* can't find valid BIOS pin config */ + + if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || + (err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || + (err = alc662_auto_create_extra_out(spec, + spec->autocfg.speaker_pins[0], + "Speaker")) < 0 || + (err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], + "Headphone")) < 0 || + (err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + return err; + + spec->multiout.max_channels = spec->multiout.num_dacs * 2; + + if (spec->autocfg.dig_out_pin) + spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; + + if (spec->kctl_alloc) + spec->mixers[spec->num_mixers++] = spec->kctl_alloc; + + spec->num_mux_defs = 1; + spec->input_mux = &spec->private_imux; + + if (err < 0) + return err; + else if (err > 0) + /* hack - override the init verbs */ + spec->init_verbs[0] = alc662_auto_init_verbs; + spec->mixers[spec->num_mixers] = alc662_capture_mixer; + spec->num_mixers++; + return err; +} + +/* additional initialization for auto-configuration model */ +static void alc662_auto_init(struct hda_codec *codec) +{ + alc662_auto_init_multi_out(codec); + alc662_auto_init_hp_out(codec); + alc662_auto_init_analog_input(codec); +} + +static int patch_alc662(struct hda_codec *codec) +{ + struct alc_spec *spec; + int err, board_config; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return -ENOMEM; + + codec->spec = spec; + + board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, + alc662_models, + alc662_cfg_tbl); + if (board_config < 0) { + printk(KERN_INFO "hda_codec: Unknown model for ALC662, " + "trying auto-probe from BIOS...\n"); + board_config = ALC662_AUTO; + } + + if (board_config == ALC662_AUTO) { + /* automatic parse from the BIOS config */ + err = alc662_parse_auto_config(codec); + if (err < 0) { + alc_free(codec); + return err; + } else if (err) { + printk(KERN_INFO + "hda_codec: Cannot set up configuration " + "from BIOS. Using base mode...\n"); + board_config = ALC662_3ST_2ch_DIG; + } + } + + if (board_config != ALC662_AUTO) + setup_preset(spec, &alc662_presets[board_config]); + + spec->stream_name_analog = "ALC662 Analog"; + spec->stream_analog_playback = &alc662_pcm_analog_playback; + spec->stream_analog_capture = &alc662_pcm_analog_capture; + + spec->stream_name_digital = "ALC662 Digital"; + spec->stream_digital_playback = &alc662_pcm_digital_playback; + spec->stream_digital_capture = &alc662_pcm_digital_capture; + + if (!spec->adc_nids && spec->input_mux) { + spec->adc_nids = alc662_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); + } + + codec->patch_ops = alc_patch_ops; + if (board_config == ALC662_AUTO) + spec->init_hook = alc662_auto_init; + + return 0; +} + +/* * patch entries */ struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", - .patch = patch_alc861 }, + .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, + { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", + .patch = patch_alc883 }, + { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", + .patch = patch_alc662 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, -- cgit v0.10.2 From a961f9fe8c6b0f3138a97582e1ddf05c4560593b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Apr 2007 13:08:09 +0200 Subject: [ALSA] hda-codec - Add support of 96kHz back Added the support of 96kHz sample rate back. Although the rate isn't listed in the ACC_PAR_PCM bits but si3054 codecs do support this rate explicitly. Now fixed the deteciton code not to check this extra bit. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 2c2fcdc..59dcd97 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1368,6 +1368,11 @@ static struct hda_rate_tbl rate_bits[] = { { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ +#define AC_PAR_PCM_RATE_BITS 11 + /* up to bits 10, 384kHZ isn't supported properly */ + + /* not autodetected value */ + { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ { 0 } /* terminator */ }; @@ -1461,7 +1466,7 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, if (ratesp) { u32 rates = 0; - for (i = 0; rate_bits[i].hz; i++) { + for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) { if (val & (1 << i)) rates |= rate_bits[i].alsa_bits; } @@ -1555,13 +1560,13 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, } rate = format & 0xff00; - for (i = 0; rate_bits[i].hz; i++) + for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) if (rate_bits[i].hda_fmt == rate) { if (val & (1 << i)) break; return 0; } - if (! rate_bits[i].hz) + if (i >= AC_PAR_PCM_RATE_BITS) return 0; stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); -- cgit v0.10.2 From f12ab1e07dadecc3ac4774a7354c61baa83ff11f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 12 Apr 2007 15:51:47 +0200 Subject: [ALSA] hda-codec - clean up patch_realtek.c Trivial code clean-ups of patch_realtek.c: indent and whitespace fixes. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5d7f619..f5944e0 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -177,7 +177,7 @@ struct alc_spec { struct hda_pcm_stream *stream_analog_playback; struct hda_pcm_stream *stream_analog_capture; - char *stream_name_digital; /* digital PCM stream */ + char *stream_name_digital; /* digital PCM stream */ struct hda_pcm_stream *stream_digital_playback; struct hda_pcm_stream *stream_digital_capture; @@ -415,7 +415,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); - if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) + if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) val = alc_pin_mode_min(dir); change = pinctl != alc_pin_mode_values[val]; @@ -474,7 +474,8 @@ static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0; -} +} + static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -534,7 +535,8 @@ static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0; -} +} + static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -606,7 +608,7 @@ static void setup_preset(struct alc_spec *spec, spec->multiout.hp_nid = preset->hp_nid; spec->num_mux_defs = preset->num_mux_defs; - if (! spec->num_mux_defs) + if (!spec->num_mux_defs) spec->num_mux_defs = 1; spec->input_mux = preset->input_mux; @@ -877,7 +879,7 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = { static hda_nid_t alc880_6st_dac_nids[4] = { /* front, rear, clfe, rear_surr */ 0x02, 0x03, 0x04, 0x05 -}; +}; static struct hda_input_mux alc880_6stack_capture_source = { .num_items = 4, @@ -1488,22 +1490,24 @@ static struct hda_verb alc880_beep_init_verbs[] = { static void alc880_uniwill_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE, - 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); + 0x7000 | (0x01 << 8) | bits); } static void alc880_uniwill_unsol_event(struct hda_codec *codec, @@ -1520,14 +1524,15 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) @@ -1556,7 +1561,7 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, */ if ((res >> 28) == ALC880_HP_EVENT) alc880_uniwill_p53_hp_automute(codec); - if ((res >> 28) == ALC880_DCVOL_EVENT) + if ((res >> 28) == ALC880_DCVOL_EVENT) alc880_uniwill_p53_dcvol_automute(codec); } @@ -1796,13 +1801,15 @@ static struct hda_verb alc880_lg_init_verbs[] = { static void alc880_lg_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) @@ -1872,13 +1879,15 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { static void alc880_lg_lw_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) @@ -2149,7 +2158,7 @@ static void alc_free(struct hda_codec *codec) struct alc_spec *spec = codec->spec; unsigned int i; - if (! spec) + if (!spec) return; if (spec->kctl_alloc) { @@ -2551,7 +2560,8 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { static struct alc_config_preset alc880_presets[] = { [ALC880_3ST] = { .mixers = { alc880_three_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_3stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), @@ -2561,7 +2571,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_3ST_DIG] = { .mixers = { alc880_three_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_3stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2583,8 +2594,10 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_capture_source, }, [ALC880_5ST] = { - .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer}, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, + .mixers = { alc880_three_stack_mixer, + alc880_five_stack_mixer}, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_5stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), @@ -2592,8 +2605,10 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_capture_source, }, [ALC880_5ST_DIG] = { - .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, + .mixers = { alc880_three_stack_mixer, + alc880_five_stack_mixer }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_5stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2603,7 +2618,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_6ST] = { .mixers = { alc880_six_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_6stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), .dac_nids = alc880_6st_dac_nids, .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), @@ -2612,7 +2628,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_6ST_DIG] = { .mixers = { alc880_six_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_6stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), .dac_nids = alc880_6st_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2622,7 +2639,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_W810] = { .mixers = { alc880_w810_base_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_w810_init_verbs, alc880_gpio2_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), .dac_nids = alc880_w810_dac_nids, @@ -2633,7 +2651,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_Z71V] = { .mixers = { alc880_z71v_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_z71v_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), .dac_nids = alc880_z71v_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2644,7 +2663,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_F1734] = { .mixers = { alc880_f1734_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_f1734_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), .dac_nids = alc880_f1734_dac_nids, .hp_nid = 0x02, @@ -2654,7 +2674,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS] = { .mixers = { alc880_asus_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio1_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2665,7 +2686,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS_DIG] = { .mixers = { alc880_asus_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio1_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2677,7 +2699,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS_DIG2] = { .mixers = { alc880_asus_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio2_init_verbs }, /* use GPIO2 */ .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2689,7 +2712,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS_W1V] = { .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio1_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2738,7 +2762,7 @@ static struct alc_config_preset alc880_presets[] = { .init_hook = alc880_uniwill_p53_hp_automute, }, [ALC880_FUJITSU] = { - .mixers = { alc880_fujitsu_mixer, + .mixers = { alc880_fujitsu_mixer, alc880_pcbeep_mixer, }, .init_verbs = { alc880_volume_init_verbs, alc880_uniwill_p53_init_verbs, @@ -2781,7 +2805,7 @@ static struct alc_config_preset alc880_presets[] = { .mixers = { alc880_lg_lw_mixer }, .init_verbs = { alc880_volume_init_verbs, alc880_lg_lw_init_verbs }, - .num_dacs = 1, + .num_dacs = 1, .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), @@ -2823,18 +2847,21 @@ static struct snd_kcontrol_new alc880_control_templates[] = { }; /* add dynamic controls */ -static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val) +static int add_control(struct alc_spec *spec, int type, const char *name, + unsigned long val) { struct snd_kcontrol_new *knew; if (spec->num_kctl_used >= spec->num_kctl_alloc) { int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; - knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ - if (! knew) + /* array + terminator */ + knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); + if (!knew) return -ENOMEM; if (spec->kctl_alloc) { - memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); + memcpy(knew, spec->kctl_alloc, + sizeof(*knew) * spec->num_kctl_alloc); kfree(spec->kctl_alloc); } spec->kctl_alloc = knew; @@ -2844,7 +2871,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign knew = &spec->kctl_alloc[spec->num_kctl_used]; *knew = alc880_control_templates[type]; knew->name = kstrdup(name, GFP_KERNEL); - if (! knew->name) + if (!knew->name) return -ENOMEM; knew->private_value = val; spec->num_kctl_used++; @@ -2864,7 +2891,8 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign #define ALC880_PIN_CD_NID 0x1c /* fill in the dac_nids table from the parsed pin configuration */ -static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc880_auto_fill_dac_nids(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { hda_nid_t nid; int assigned[4]; @@ -2889,8 +2917,9 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi continue; /* search for an empty channel */ for (j = 0; j < cfg->line_outs; j++) { - if (! assigned[j]) { - spec->multiout.dac_nids[i] = alc880_idx_to_dac(j); + if (!assigned[j]) { + spec->multiout.dac_nids[i] = + alc880_idx_to_dac(j); assigned[j] = 1; break; } @@ -2905,36 +2934,54 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; + static const char *chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; hda_nid_t nid; int i, err; for (i = 0; i < cfg->line_outs; i++) { - if (! spec->multiout.dac_nids[i]) + if (!spec->multiout.dac_nids[i]) continue; nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); if (i == 2) { /* Center/LFE */ - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Center Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 2, + HDA_INPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 2, + HDA_INPUT)); + if (err < 0) return err; } else { sprintf(name, "%s Playback Volume", chname[i]); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", chname[i]); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, + HDA_INPUT)); + if (err < 0) return err; } } @@ -2949,51 +2996,57 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, int err; char name[32]; - if (! pin) + if (!pin) return 0; if (alc880_is_fixed_pin(pin)) { nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); /* specify the DAC as the extra output */ - if (! spec->multiout.hp_nid) + if (!spec->multiout.hp_nid) spec->multiout.hp_nid = nid; else spec->multiout.extra_out_nid[0] = nid; /* control HP volume/switch on the output mixer amp */ nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); sprintf(name, "%s Playback Volume", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); + if (err < 0) return err; } else if (alc880_is_multi_pin(pin)) { /* set manual connection */ /* we have only a switch on HP-out PIN */ sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; } return 0; } /* create input playback/capture controls for the given pin */ -static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname, +static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, + const char *ctlname, int idx, hda_nid_t mix_nid) { char name[32]; int err; sprintf(name, "%s Playback Volume", ctlname); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", ctlname); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); + if (err < 0) return err; return 0; } @@ -3013,8 +3066,10 @@ static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, idx, 0x0b); if (err < 0) return err; - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; - imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]); + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; + imux->items[imux->num_items].index = + alc880_input_pin_idx(cfg->input_pins[i]); imux->num_items++; } } @@ -3026,8 +3081,10 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, int dac_idx) { /* set as output */ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); /* need the manual connection? */ if (alc880_is_multi_pin(nid)) { struct alc_spec *spec = codec->spec; @@ -3071,37 +3128,52 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (alc880_is_input_pin(nid)) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); if (nid != ALC880_PIN_CD_NID) - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); } } } /* 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 */ +/* return 1 if successful, 0 if the proper config is not found, + * or a negative error code + */ static int alc880_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc880_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc880_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || - (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc880_auto_create_extra_out(spec, - spec->autocfg.speaker_pins[0], - "Speaker")) < 0 || - (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], - "Headphone")) < 0 || - (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc880_auto_create_extra_out(spec, + spec->autocfg.speaker_pins[0], + "Speaker"); + if (err < 0) + return err; + err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], + "Headphone"); + if (err < 0) + return err; + err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -3161,7 +3233,7 @@ static int patch_alc880(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using 3-stack mode...\n"); @@ -3180,14 +3252,16 @@ static int patch_alc880(struct hda_codec *codec) spec->stream_digital_playback = &alc880_pcm_digital_playback; spec->stream_digital_capture = &alc880_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ + /* get type */ + wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (wcap != AC_WID_AUD_IN) { spec->adc_nids = alc880_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); - spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer; + spec->mixers[spec->num_mixers] = + alc880_capture_alt_mixer; spec->num_mixers++; } else { spec->adc_nids = alc880_adc_nids; @@ -3329,7 +3403,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = { HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), { } /* end */ -}; +}; static struct snd_kcontrol_new alc260_input_mixer[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), @@ -3545,7 +3619,9 @@ static struct hda_verb alc260_init_verbs[] = { {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* unmute LINE-2 out pin */ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ + /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & + * Line In 2 = 0x03 + */ /* mute CD */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* mute Line In */ @@ -3593,7 +3669,9 @@ static struct hda_verb alc260_hp_init_verbs[] = { {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* mute pin widget amp left and right (no gain on this amp) */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ + /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & + * Line In 2 = 0x03 + */ /* unmute CD */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /* unmute Line In */ @@ -3641,7 +3719,9 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = { {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* mute pin widget amp left and right (no gain on this amp) */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ + /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & + * Line In 2 = 0x03 + */ /* unmute CD */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /* unmute Line In */ @@ -3791,7 +3871,9 @@ static struct hda_verb alc260_acer_init_verbs[] = { {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ + /* Unmute Line-out pin widget amp left and right + * (no equiv mixer ctrl) + */ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -4106,10 +4188,12 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, return 0; /* N/A */ snprintf(name, sizeof(name), "%s Playback Volume", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); + if (err < 0) return err; snprintf(name, sizeof(name), "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); + if (err < 0) return err; return 1; } @@ -4145,7 +4229,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, if (err < 0) return err; } - return 0; + return 0; } /* create playback/capture controls for input pins */ @@ -4159,20 +4243,24 @@ static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, if (cfg->input_pins[i] >= 0x12) { idx = cfg->input_pins[i] - 0x12; err = new_analog_input(spec, cfg->input_pins[i], - auto_pin_cfg_labels[i], idx, 0x07); + auto_pin_cfg_labels[i], idx, + 0x07); if (err < 0) return err; - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; imux->items[imux->num_items].index = idx; imux->num_items++; } - if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){ + if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ idx = cfg->input_pins[i] - 0x09; err = new_analog_input(spec, cfg->input_pins[i], - auto_pin_cfg_labels[i], idx, 0x07); + auto_pin_cfg_labels[i], idx, + 0x07); if (err < 0) return err; - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; imux->items[imux->num_items].index = idx; imux->num_items++; } @@ -4185,14 +4273,15 @@ static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, int sel_idx) { /* set as output */ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); /* need the manual connection? */ if (nid >= 0x12) { int idx = nid - 0x12; snd_hda_codec_write(codec, idx + 0x0b, 0, AC_VERB_SET_CONNECT_SEL, sel_idx); - } } @@ -4202,7 +4291,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) hda_nid_t nid; alc_subsystem_id(codec, 0x10, 0x15, 0x0f); - nid = spec->autocfg.line_out_pins[0]; + nid = spec->autocfg.line_out_pins[0]; if (nid) alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); @@ -4213,7 +4302,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) nid = spec->autocfg.hp_pins[0]; if (nid) alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); -} +} #define ALC260_PIN_CD_NID 0x16 static void alc260_auto_init_analog_input(struct hda_codec *codec) @@ -4224,10 +4313,13 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (nid >= 0x12) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); if (nid != ALC260_PIN_CD_NID) - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); } } @@ -4247,8 +4339,8 @@ static struct hda_verb alc260_volume_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -4283,14 +4375,17 @@ static int alc260_parse_auto_config(struct hda_codec *codec) int err; static hda_nid_t alc260_ignore[] = { 0x17, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc260_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc260_ignore); + if (err < 0) return err; - if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0) + err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) return err; - if (! spec->kctl_alloc) + if (!spec->kctl_alloc) return 0; /* can't find valid BIOS pin config */ - if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = 2; @@ -4506,7 +4601,7 @@ static int patch_alc260(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -4575,7 +4670,8 @@ static struct hda_input_mux alc882_capture_source = { #define alc882_mux_enum_info alc_mux_enum_info #define alc882_mux_enum_get alc_mux_enum_get -static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; @@ -4589,7 +4685,7 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; for (i = 0; i < imux->num_items; i++) { unsigned int v = (i == idx) ? 0x7000 : 0x7080; @@ -4752,7 +4848,7 @@ static struct hda_verb alc882_eapd_verbs[] = { /* change to EAPD mode */ {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, - { } + { } }; /* Mac Pro test */ @@ -4817,6 +4913,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = { { } }; + static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) { unsigned int gpiostate, gpiomask, gpiodir; @@ -4865,8 +4962,8 @@ static struct hda_verb alc882_auto_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -5044,15 +5141,17 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, { /* set as output */ struct alc_spec *spec = codec->spec; - int idx; - + int idx; + if (spec->multiout.dac_nids[dac_idx] == 0x25) idx = 4; else idx = spec->multiout.dac_nids[dac_idx] - 2; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); } @@ -5064,9 +5163,10 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec) alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { - hda_nid_t nid = spec->autocfg.line_out_pins[i]; + hda_nid_t nid = spec->autocfg.line_out_pins[i]; if (nid) - alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); + alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, + i); } } @@ -5077,7 +5177,8 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec) pin = spec->autocfg.hp_pins[0]; if (pin) /* connect to front */ - alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */ + /* use dac 0 */ + alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); } #define alc882_is_input_pin(nid) alc880_is_input_pin(nid) @@ -5091,10 +5192,13 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (alc882_is_input_pin(nid)) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); if (nid != ALC882_PIN_CD_NID) - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); } } @@ -5156,7 +5260,7 @@ static int patch_alc882(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -5180,14 +5284,16 @@ static int patch_alc882(struct hda_codec *codec) spec->stream_digital_playback = &alc882_pcm_digital_playback; spec->stream_digital_capture = &alc882_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ + /* get type */ + wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (wcap != AC_WID_AUD_IN) { spec->adc_nids = alc882_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); - spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer; + spec->mixers[spec->num_mixers] = + alc882_capture_alt_mixer; spec->num_mixers++; } else { spec->adc_nids = alc882_adc_nids; @@ -5227,6 +5333,7 @@ static hda_nid_t alc883_adc_nids[2] = { /* ADC1-2 */ 0x08, 0x09, }; + /* input MUX */ /* FIXME: should be a matrix-type input source selection */ @@ -5266,7 +5373,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; for (i = 0; i < imux->num_items; i++) { unsigned int v = (i == idx) ? 0x7000 : 0x7080; @@ -5276,6 +5383,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, *cur_val = idx; return 1; } + /* * 2ch mode */ @@ -5528,7 +5636,7 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = { .put = alc883_mux_enum_put, }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), @@ -5553,7 +5661,7 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { .put = alc883_mux_enum_put, }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), @@ -5576,7 +5684,7 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { .put = alc883_mux_enum_put, }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc883_chmode_mixer[] = { { @@ -5678,9 +5786,9 @@ static struct hda_verb alc883_tagra_verbs[] = { {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, - {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, + {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, { } /* end */ }; @@ -5696,14 +5804,17 @@ static struct hda_verb alc883_lenovo_101e_verbs[] = { static void alc883_tagra_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); + 0x80, bits); + snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, + present ? 1 : 3); } static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) @@ -5715,31 +5826,33 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, @@ -5765,8 +5878,8 @@ static struct hda_verb alc883_auto_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -5802,13 +5915,13 @@ static struct hda_verb alc883_auto_init_verbs[] = { {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* Input mixer2 */ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, { } @@ -5913,7 +6026,7 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc883_capture_source, - }, + }, [ALC883_3ST_6ch] = { .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs }, @@ -5925,7 +6038,7 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc883_capture_source, - }, + }, [ALC883_6ST_DIG] = { .mixers = { alc883_base_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs }, @@ -6048,8 +6161,8 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, { /* set as output */ struct alc_spec *spec = codec->spec; - int idx; - + int idx; + if (spec->multiout.dac_nids[dac_idx] == 0x25) idx = 4; else @@ -6070,9 +6183,10 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { - hda_nid_t nid = spec->autocfg.line_out_pins[i]; + hda_nid_t nid = spec->autocfg.line_out_pins[i]; if (nid) - alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); + alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, + i); } } @@ -6160,7 +6274,7 @@ static int patch_alc883(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -6179,7 +6293,7 @@ static int patch_alc883(struct hda_codec *codec) spec->stream_digital_playback = &alc883_pcm_digital_playback; spec->stream_digital_capture = &alc883_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { spec->adc_nids = alc883_adc_nids; spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); } @@ -6316,8 +6430,8 @@ static struct hda_verb alc262_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -6374,7 +6488,7 @@ static struct hda_verb alc262_init_verbs[] = { {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, { } }; @@ -6401,7 +6515,7 @@ static void alc262_hippo_automute(struct hda_codec *codec, int force) struct alc_spec *spec = codec->spec; unsigned int mute; - if (force || ! spec->sense_updated) { + if (force || !spec->sense_updated) { unsigned int present; /* need to execute and sync at first */ snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -6441,7 +6555,7 @@ static void alc262_hippo1_automute(struct hda_codec *codec, int force) struct alc_spec *spec = codec->spec; unsigned int mute; - if (force || ! spec->sense_updated) { + if (force || !spec->sense_updated) { unsigned int present; /* need to execute and sync at first */ snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -6514,7 +6628,7 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force) struct alc_spec *spec = codec->spec; unsigned int mute; - if (force || ! spec->sense_updated) { + if (force || !spec->sense_updated) { unsigned int present; /* need to execute and sync at first */ snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -6619,7 +6733,8 @@ static struct hda_verb alc262_EAPD_verbs[] = { }; /* add playback controls from the parsed DAC table */ -static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { hda_nid_t nid; int err; @@ -6630,26 +6745,39 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct nid = cfg->line_out_pins[0]; if (nid) { - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume", - HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Front Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Front Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; } nid = cfg->speaker_pins[0]; if (nid) { if (nid == 0x16) { - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", - HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Speaker Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Speaker Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; } else { - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Speaker Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; } } @@ -6657,23 +6785,33 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct if (nid) { /* spec->multiout.hp_nid = 2; */ if (nid == 0x16) { - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", - HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Headphone Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; } else { - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; } } - return 0; + return 0; } /* identical with ALC880 */ -#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls +#define alc262_auto_create_analog_input_ctls \ + alc880_auto_create_analog_input_ctls /* * generic initialization of ADC, input mixers and output mixers @@ -6691,8 +6829,8 @@ static struct hda_verb alc262_volume_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -6752,8 +6890,8 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -6935,13 +7073,17 @@ static int alc262_parse_auto_config(struct hda_codec *codec) int err; static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc262_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc262_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -7065,7 +7207,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, - }, + }, [ALC262_HP_BPC_D7000_WF] = { .mixers = { alc262_HP_BPC_WildWest_mixer }, .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, @@ -7075,7 +7217,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, - }, + }, [ALC262_HP_BPC_D7000_WL] = { .mixers = { alc262_HP_BPC_WildWest_mixer, alc262_HP_BPC_WildWest_option_mixer }, @@ -7086,7 +7228,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, - }, + }, [ALC262_BENQ_ED8] = { .mixers = { alc262_base_mixer }, .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, @@ -7096,7 +7238,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, - }, + }, }; static int patch_alc262(struct hda_codec *codec) @@ -7111,7 +7253,9 @@ static int patch_alc262(struct hda_codec *codec) codec->spec = spec; #if 0 - /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is under-run */ + /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is + * under-run + */ { int tmp; snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); @@ -7137,7 +7281,7 @@ static int patch_alc262(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -7156,15 +7300,17 @@ static int patch_alc262(struct hda_codec *codec) spec->stream_digital_playback = &alc262_pcm_digital_playback; spec->stream_digital_capture = &alc262_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ + /* get type */ + wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (wcap != AC_WID_AUD_IN) { spec->adc_nids = alc262_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); - spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer; + spec->mixers[spec->num_mixers] = + alc262_capture_alt_mixer; spec->num_mixers++; } else { spec->adc_nids = alc262_adc_nids; @@ -7192,7 +7338,9 @@ static int patch_alc262(struct hda_codec *codec) static struct hda_verb alc861_threestack_ch2_init[] = { /* set pin widget 1Ah (line in) for input */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ + /* set pin widget 18h (mic1/2) for input, for mic also enable + * the vref + */ { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, @@ -7249,7 +7397,9 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { static struct hda_verb alc861_asus_ch2_init[] = { /* set pin widget 1Ah (line in) for input */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ + /* set pin widget 18h (mic1/2) for input, for mic also enable + * the vref + */ { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, @@ -7304,7 +7454,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), - + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7338,7 +7488,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), - + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7380,7 +7530,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = { }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { /* output mixer control */ @@ -7401,7 +7551,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), - + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7422,7 +7572,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc861_asus_mixer[] = { /* output mixer control */ @@ -7442,8 +7592,8 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */ - + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7527,7 +7677,7 @@ static struct hda_verb alc861_base_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7537,7 +7687,8 @@ static struct hda_verb alc861_base_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } @@ -7588,7 +7739,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7598,7 +7749,8 @@ static struct hda_verb alc861_threestack_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } }; @@ -7617,7 +7769,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-E for HP out (front panel) */ - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80 + /* this has to be set to VREF80 */ + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* route front PCM to HP */ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-F for mic-in (front panel) with vref */ @@ -7648,7 +7801,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7658,7 +7811,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } }; @@ -7667,7 +7821,9 @@ static struct hda_verb alc861_asus_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ - /* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/ + /* port-A for surround (rear panel) + * according to codec#0 this is the HP jack + */ { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ /* route front PCM to HP */ { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, @@ -7679,7 +7835,8 @@ static struct hda_verb alc861_asus_init_verbs[] = { { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-E for HP out (front panel) */ - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */ + /* this has to be set to VREF80 */ + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* route front PCM to HP */ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-F for mic-in (front panel) with vref */ @@ -7709,7 +7866,7 @@ static struct hda_verb alc861_asus_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, /* Output 0~12 step */ + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7719,7 +7876,8 @@ static struct hda_verb alc861_asus_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */ + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } }; @@ -7738,7 +7896,7 @@ static struct hda_verb alc861_auto_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ -// {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* Unmute DAC0~3 & spdif out*/ @@ -7771,21 +7929,21 @@ static struct hda_verb alc861_auto_init_verbs[] = { {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, // set Mic 1 + {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ { } }; static struct hda_verb alc861_toshiba_init_verbs[] = { {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, - + { } }; @@ -7853,7 +8011,8 @@ static struct hda_input_mux alc861_capture_source = { }; /* fill in the dac_nids table from the parsed pin configuration */ -static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc861_auto_fill_dac_nids(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { int i; hda_nid_t nid; @@ -7876,29 +8035,40 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; + static const char *chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; hda_nid_t nid; int i, idx, err; for (i = 0; i < cfg->line_outs; i++) { nid = spec->multiout.dac_nids[i]; - if (! nid) + if (!nid) continue; if (nid == 0x05) { /* Center/LFE */ - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; } else { - for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++) + for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; + idx++) if (nid == alc861_dac_nids[idx]) break; sprintf(name, "%s Playback Switch", chname[idx]); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; } } @@ -7910,13 +8080,15 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) int err; hda_nid_t nid; - if (! pin) + if (!pin) return 0; if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { nid = 0x03; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; spec->multiout.hp_nid = nid; } @@ -7924,32 +8096,33 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) } /* create playback/capture controls for input pins */ -static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { struct hda_input_mux *imux = &spec->private_imux; int i, err, idx, idx1; for (i = 0; i < AUTO_PIN_LAST; i++) { - switch(cfg->input_pins[i]) { + switch (cfg->input_pins[i]) { case 0x0c: idx1 = 1; - idx = 2; // Line In + idx = 2; /* Line In */ break; case 0x0f: idx1 = 2; - idx = 2; // Line In + idx = 2; /* Line In */ break; case 0x0d: idx1 = 0; - idx = 1; // Mic In + idx = 1; /* Mic In */ break; - case 0x10: + case 0x10: idx1 = 3; - idx = 1; // Mic In + idx = 1; /* Mic In */ break; case 0x11: idx1 = 4; - idx = 0; // CD + idx = 0; /* CD */ break; default: continue; @@ -7962,7 +8135,7 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const str imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; imux->items[imux->num_items].index = idx1; - imux->num_items++; + imux->num_items++; } return 0; } @@ -7987,13 +8160,16 @@ static struct snd_kcontrol_new alc861_capture_mixer[] = { { } /* end */ }; -static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, +static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, + hda_nid_t nid, int pin_type, int dac_idx) { /* set as output */ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); } @@ -8006,7 +8182,8 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec) for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; if (nid) - alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]); + alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, + spec->multiout.dac_nids[i]); } } @@ -8017,7 +8194,8 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec) pin = spec->autocfg.hp_pins[0]; if (pin) /* connect to front */ - alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]); + alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, + spec->multiout.dac_nids[0]); } static void alc861_auto_init_analog_input(struct hda_codec *codec) @@ -8027,31 +8205,43 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; - if ((nid>=0x0c) && (nid <=0x11)) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + if (nid >= 0x0c && nid <= 0x11) { + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); } } } /* 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 */ +/* return 1 if successful, 0 if the proper config is not found, + * or a negative error code + */ static int alc861_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc861_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc861_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || - (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 || - (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); + if (err < 0) + return err; + err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -8179,7 +8369,8 @@ static struct alc_config_preset alc861_presets[] = { }, [ALC861_TOSHIBA] = { .mixers = { alc861_toshiba_mixer }, - .init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs }, + .init_verbs = { alc861_base_init_verbs, + alc861_toshiba_init_verbs }, .num_dacs = ARRAY_SIZE(alc861_dac_nids), .dac_nids = alc861_dac_nids, .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), @@ -8231,7 +8422,7 @@ static int patch_alc861(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - codec->spec = spec; + codec->spec = spec; board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, alc861_models, @@ -8249,7 +8440,7 @@ static int patch_alc861(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -8336,7 +8527,7 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; for (i = 0; i < imux->num_items; i++) { unsigned int v = (i == idx) ? 0x7000 : 0x7080; @@ -8755,7 +8946,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, int i, err; for (i = 0; i < cfg->line_outs; i++) { - if (! spec->multiout.dac_nids[i]) + if (!spec->multiout.dac_nids[i]) continue; nid_v = alc861vd_idx_to_mixer_vol( alc880_dac_to_idx( @@ -8766,36 +8957,42 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, if (i == 2) { /* Center/LFE */ - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, - "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(nid_v, 1, - 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Center Playback Volume", + HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, - "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(nid_v, 2, - 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, - "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid_s, 1, - 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, + HDA_INPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, - "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid_s, 2, - 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, + HDA_INPUT)); + if (err < 0) return err; } else { sprintf(name, "%s Playback Volume", chname[i]); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid_v, 3, - 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", chname[i]); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid_v, 3, - 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid_v, 3, 2, + HDA_INPUT)); + if (err < 0) return err; } } @@ -8812,13 +9009,13 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, int err; char name[32]; - if (! pin) + if (!pin) return 0; if (alc880_is_fixed_pin(pin)) { nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); /* specify the DAC as the extra output */ - if (! spec->multiout.hp_nid) + if (!spec->multiout.hp_nid) spec->multiout.hp_nid = nid_v; else spec->multiout.extra_out_nid[0] = nid_v; @@ -8829,22 +9026,22 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, alc880_fixed_pin_idx(pin)); sprintf(name, "%s Playback Volume", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, - HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, - HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); + if (err < 0) return err; } else if (alc880_is_multi_pin(pin)) { /* set manual connection */ /* we have only a switch on HP-out PIN */ sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(pin, 3, 0, - HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; } return 0; @@ -8861,21 +9058,31 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) int err; static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc861vd_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc861vd_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || - (err = alc861vd_auto_create_multi_out_ctls(spec, - &spec->autocfg)) < 0 || - (err = alc861vd_auto_create_extra_out(spec, - spec->autocfg.speaker_pins[0], "Speaker")) < 0 || - (err = alc861vd_auto_create_extra_out(spec, - spec->autocfg.hp_pins[0], "Headphone")) < 0 || - (err = alc880_auto_create_analog_input_ctls(spec, - &spec->autocfg)) < 0) + err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861vd_auto_create_extra_out(spec, + spec->autocfg.speaker_pins[0], + "Speaker"); + if (err < 0) + return err; + err = alc861vd_auto_create_extra_out(spec, + spec->autocfg.hp_pins[0], + "Headphone"); + if (err < 0) + return err; + err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -8930,7 +9137,7 @@ static int patch_alc861vd(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -9024,7 +9231,7 @@ static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; for (i = 0; i < imux->num_items; i++) { unsigned int v = (i == idx) ? 0x7000 : 0x7080; @@ -9370,31 +9577,33 @@ static struct snd_kcontrol_new alc662_capture_mixer[] = { static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, @@ -9457,7 +9666,7 @@ static struct alc_config_preset alc662_presets[] = { .channel_mode = alc662_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc662_capture_source, - }, + }, [ALC662_3ST_6ch] = { .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, .init_verbs = { alc662_init_verbs }, @@ -9469,7 +9678,7 @@ static struct alc_config_preset alc662_presets[] = { .channel_mode = alc662_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc662_capture_source, - }, + }, [ALC662_5ST_DIG] = { .mixers = { alc662_base_mixer, alc662_chmode_mixer }, .init_verbs = { alc662_init_verbs }, @@ -9523,33 +9732,39 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, /* Center/LFE */ err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); + HDA_COMPOSE_AMP_VAL(nid, 1, 0, + HDA_OUTPUT)); if (err < 0) return err; err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT)); + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); if (err < 0) return err; err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT)); + HDA_COMPOSE_AMP_VAL(nid, 1, 2, + HDA_INPUT)); if (err < 0) return err; err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT)); + HDA_COMPOSE_AMP_VAL(nid, 2, 2, + HDA_INPUT)); if (err < 0) return err; } else { sprintf(name, "%s Playback Volume", chname[i]); err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); if (err < 0) return err; sprintf(name, "%s Playback Switch", chname[i]); err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); + HDA_COMPOSE_AMP_VAL(nid, 3, 2, + HDA_INPUT)); if (err < 0) return err; } @@ -9704,14 +9919,23 @@ static int alc662_parse_auto_config(struct hda_codec *codec) if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || - (err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc662_auto_create_extra_out(spec, - spec->autocfg.speaker_pins[0], - "Speaker")) < 0 || - (err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], - "Headphone")) < 0 || - (err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc662_auto_create_extra_out(spec, + spec->autocfg.speaker_pins[0], + "Speaker"); + if (err < 0) + return err; + err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], + "Headphone"); + if (err < 0) + return err; + err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; -- cgit v0.10.2 From 5930ca41857f57e130b4438a9a261b2ab91f6fcf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 16 Apr 2007 11:23:56 +0200 Subject: [ALSA] hda-codec - Allow opening SPDIF while analog dup mode Allow opening the dedicated SPDIF stream while running on analog dup mode. Then the SPDIF stream is once reset and assigned for the new stream. It's useful for exclusive SPDIF output like AC3/DTS. (In the former version, you had to close once the analog stream to play the exclusive digital stream.) Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 59dcd97..1fa93bd25 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1916,10 +1916,9 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) { mutex_lock(&codec->spdif_mutex); - if (mout->dig_out_used) { - mutex_unlock(&codec->spdif_mutex); - return -EBUSY; /* already being used */ - } + if (mout->dig_out_used == HDA_DIG_ANALOG_DUP) + /* already opened as analog dup; reset it once */ + snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); mout->dig_out_used = HDA_DIG_EXCLUSIVE; mutex_unlock(&codec->spdif_mutex); return 0; -- cgit v0.10.2 From 756e2b014349e90aca1d0432498d1b35e5445566 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 16 Apr 2007 11:27:07 +0200 Subject: [ALSA] hda-intel - Merge hda-codec module to a single module Merge hda-codec module to a single hda-intel module since this is the only user right now. Although hda-codec stuff is designed to be used universally from different controller drivers, currently only one controller interface (and compatibles) are used. So, let's merge them to a single module to save memory. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 60d7b05..b2484bb 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -1,5 +1,8 @@ snd-hda-intel-objs := hda_intel.o -snd-hda-codec-objs := hda_codec.o \ +# since snd-hda-intel is the only driver using hda-codec, +# merge it into a single module although it was originally +# designed to be individual modules +snd-hda-intel-objs += hda_codec.o \ hda_generic.o \ patch_realtek.o \ patch_cmedia.o \ @@ -10,7 +13,7 @@ snd-hda-codec-objs := hda_codec.o \ patch_conexant.o \ patch_via.o ifdef CONFIG_PROC_FS -snd-hda-codec-objs += hda_proc.o +snd-hda-intel-objs += hda_proc.o endif -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o snd-hda-codec.o +obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 1fa93bd25..fe4acfa 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include "hda_codec.h" @@ -34,11 +33,6 @@ #include "hda_local.h" -MODULE_AUTHOR("Takashi Iwai "); -MODULE_DESCRIPTION("Universal interface for High Definition Audio Codec"); -MODULE_LICENSE("GPL"); - - /* * vendor / preset table */ @@ -90,8 +84,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire return res; } -EXPORT_SYMBOL(snd_hda_codec_read); - /** * snd_hda_codec_write - send a single command without waiting for response * @codec: the HDA codec @@ -114,8 +106,6 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, return err; } -EXPORT_SYMBOL(snd_hda_codec_write); - /** * snd_hda_sequence_write - sequence writes * @codec: the HDA codec @@ -130,8 +120,6 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq) snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); } -EXPORT_SYMBOL(snd_hda_sequence_write); - /** * snd_hda_get_sub_nodes - get the range of sub nodes * @codec: the HDA codec @@ -150,8 +138,6 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *sta return (int)(parm & 0x7fff); } -EXPORT_SYMBOL(snd_hda_get_sub_nodes); - /** * snd_hda_get_connections - get connection list * @codec: the HDA codec @@ -268,8 +254,6 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) return 0; } -EXPORT_SYMBOL(snd_hda_queue_unsol_event); - /* * process queueud unsolicited events */ @@ -298,7 +282,7 @@ static void process_unsol_events(struct work_struct *work) /* * initialize unsolicited queue */ -static int init_unsol_queue(struct hda_bus *bus) +static int __devinit init_unsol_queue(struct hda_bus *bus) { struct hda_bus_unsolicited *unsol; @@ -355,8 +339,9 @@ static int snd_hda_bus_dev_free(struct snd_device *device) * * Returns 0 if successful, or a negative error code. */ -int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, - struct hda_bus **busp) +int __devinit snd_hda_bus_new(struct snd_card *card, + const struct hda_bus_template *temp, + struct hda_bus **busp) { struct hda_bus *bus; int err; @@ -394,12 +379,11 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, return 0; } -EXPORT_SYMBOL(snd_hda_bus_new); - /* * find a matching codec preset */ -static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec) +static const struct hda_codec_preset __devinit * +find_codec_preset(struct hda_codec *codec) { const struct hda_codec_preset **tbl, *preset; @@ -450,7 +434,7 @@ void snd_hda_get_codec_name(struct hda_codec *codec, /* * look for an AFG and MFG nodes */ -static void setup_fg_nodes(struct hda_codec *codec) +static void __devinit setup_fg_nodes(struct hda_codec *codec) { int i, total_nodes; hda_nid_t nid; @@ -517,8 +501,8 @@ static void init_amp_hash(struct hda_codec *codec); * * Returns 0 if successful, or a negative error code. */ -int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, - struct hda_codec **codecp) +int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, + struct hda_codec **codecp) { struct hda_codec *codec; char component[13]; @@ -603,8 +587,6 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, return 0; } -EXPORT_SYMBOL(snd_hda_codec_new); - /** * snd_hda_codec_setup_stream - set up the codec for streaming * @codec: the CODEC to set up @@ -627,8 +609,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stre snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); } -EXPORT_SYMBOL(snd_hda_codec_setup_stream); - /* * amp access functions */ @@ -639,7 +619,7 @@ EXPORT_SYMBOL(snd_hda_codec_setup_stream); #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) /* initialize the hash table */ -static void init_amp_hash(struct hda_codec *codec) +static void __devinit init_amp_hash(struct hda_codec *codec) { memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash)); codec->num_amp_entries = 0; @@ -1169,7 +1149,8 @@ static struct snd_kcontrol_new dig_mixes[] = { * * Returns 0 if successful, or a negative error code. */ -int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) +int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec, + hda_nid_t nid) { int err; struct snd_kcontrol *kctl; @@ -1261,7 +1242,8 @@ static struct snd_kcontrol_new dig_in_ctls[] = { * * Returns 0 if successful, or a negative error code. */ -int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) +int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec, + hda_nid_t nid) { int err; struct snd_kcontrol *kctl; @@ -1311,7 +1293,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, * * Returns 0 if successful, otherwise a negative error code. */ -int snd_hda_build_controls(struct hda_bus *bus) +int __devinit snd_hda_build_controls(struct hda_bus *bus) { struct list_head *p; @@ -1342,8 +1324,6 @@ int snd_hda_build_controls(struct hda_bus *bus) return 0; } -EXPORT_SYMBOL(snd_hda_build_controls); - /* * stream formats */ @@ -1433,8 +1413,6 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, return val; } -EXPORT_SYMBOL(snd_hda_calc_stream_format); - /** * snd_hda_query_supported_pcm - query the supported PCM rates and formats * @codec: the HDA codec @@ -1688,7 +1666,7 @@ static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream * * This function returns 0 if successfull, or a negative error code. */ -int snd_hda_build_pcms(struct hda_bus *bus) +int __devinit snd_hda_build_pcms(struct hda_bus *bus) { struct list_head *p; @@ -1716,8 +1694,6 @@ int snd_hda_build_pcms(struct hda_bus *bus) return 0; } -EXPORT_SYMBOL(snd_hda_build_pcms); - /** * snd_hda_check_board_config - compare the current codec with the config table * @codec: the HDA codec @@ -1731,9 +1707,9 @@ EXPORT_SYMBOL(snd_hda_build_pcms); * * If no entries are matching, the function returns a negative value. */ -int snd_hda_check_board_config(struct hda_codec *codec, - int num_configs, const char **models, - const struct snd_pci_quirk *tbl) +int __devinit snd_hda_check_board_config(struct hda_codec *codec, + int num_configs, const char **models, + const struct snd_pci_quirk *tbl) { if (codec->bus->modelname && models) { int i; @@ -1783,7 +1759,8 @@ int snd_hda_check_board_config(struct hda_codec *codec, * * Returns 0 if successful, or a negative error code. */ -int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) +int __devinit snd_hda_add_new_ctls(struct hda_codec *codec, + struct snd_kcontrol_new *knew) { int err; @@ -2040,7 +2017,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o * Helper for automatic ping configuration */ -static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) +static int __devinit is_in_nid_list(hda_nid_t nid, hda_nid_t *list) { for (; *list; list++) if (*list == nid) @@ -2065,8 +2042,9 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, * respectively. */ -int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, - hda_nid_t *ignore_nids) +int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, + struct auto_pin_cfg *cfg, + hda_nid_t *ignore_nids) { hda_nid_t nid, nid_start; int i, j, nodes; @@ -2273,8 +2251,6 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) return 0; } -EXPORT_SYMBOL(snd_hda_suspend); - /** * snd_hda_resume - resume the codecs * @bus: the HDA bus @@ -2297,8 +2273,6 @@ int snd_hda_resume(struct hda_bus *bus) return 0; } -EXPORT_SYMBOL(snd_hda_resume); - /** * snd_hda_resume_ctls - resume controls in the new control list * @codec: the HDA codec @@ -2357,19 +2331,3 @@ int snd_hda_resume_spdif_in(struct hda_codec *codec) return snd_hda_resume_ctls(codec, dig_in_ctls); } #endif - -/* - * INIT part - */ - -static int __init alsa_hda_init(void) -{ - return 0; -} - -static void __exit alsa_hda_exit(void) -{ -} - -module_init(alsa_hda_init) -module_exit(alsa_hda_exit) -- cgit v0.10.2 From 0ba21762d3966d242cb2486a76f83e5a34933f95 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 16 Apr 2007 11:29:14 +0200 Subject: [ALSA] hda-codec - Code clean up Trivial code clean-ups to follow the standard coding styles. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index fe4acfa..2fdd165 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -71,12 +71,13 @@ static struct hda_vendor_id hda_vendor_ids[] = { * * Returns the obtained response value, or -1 for an error. */ -unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, +unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, + int direct, unsigned int verb, unsigned int parm) { unsigned int res; mutex_lock(&codec->bus->cmd_mutex); - if (! codec->bus->ops.command(codec, nid, direct, verb, parm)) + if (!codec->bus->ops.command(codec, nid, direct, verb, parm)) res = codec->bus->ops.get_response(codec); else res = (unsigned int)-1; @@ -129,7 +130,8 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq) * Parse the NID and store the start NID of its sub-nodes. * Returns the number of sub-nodes. */ -int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id) +int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, + hda_nid_t *start_id) { unsigned int parm; @@ -173,12 +175,13 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, conn_len = parm & AC_CLIST_LENGTH; mask = (1 << (shift-1)) - 1; - if (! conn_len) + if (!conn_len) return 0; /* no connection */ if (conn_len == 1) { /* single connection */ - parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, 0); + parm = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONNECT_LIST, 0); conn_list[0] = parm & mask; return 1; } @@ -193,18 +196,21 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, if (i % num_elems == 0) parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, i); - range_val = !! (parm & (1 << (shift-1))); /* ranges */ + range_val = !!(parm & (1 << (shift-1))); /* ranges */ val = parm & mask; parm >>= shift; if (range_val) { /* ranges between the previous and this one */ - if (! prev_nid || prev_nid >= val) { - snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val); + if (!prev_nid || prev_nid >= val) { + snd_printk(KERN_WARNING "hda_codec: " + "invalid dep_range_val %x:%x\n", + prev_nid, val); continue; } for (n = prev_nid + 1; n <= val; n++) { if (conns >= max_conns) { - snd_printk(KERN_ERR "Too many connections\n"); + snd_printk(KERN_ERR + "Too many connections\n"); return -EINVAL; } conn_list[conns++] = n; @@ -239,7 +245,8 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) struct hda_bus_unsolicited *unsol; unsigned int wp; - if ((unsol = bus->unsol) == NULL) + unsol = bus->unsol; + if (!unsol) return 0; wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE; @@ -271,7 +278,7 @@ static void process_unsol_events(struct work_struct *work) rp <<= 1; res = unsol->queue[rp]; caddr = unsol->queue[rp + 1]; - if (! (caddr & (1 << 4))) /* no unsolicited event? */ + if (!(caddr & (1 << 4))) /* no unsolicited event? */ continue; codec = bus->caddr_tbl[caddr & 0x0f]; if (codec && codec->patch_ops.unsol_event) @@ -290,8 +297,9 @@ static int __devinit init_unsol_queue(struct hda_bus *bus) return 0; unsol = kzalloc(sizeof(*unsol), GFP_KERNEL); - if (! unsol) { - snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); + if (!unsol) { + snd_printk(KERN_ERR "hda_codec: " + "can't allocate unsolicited queue\n"); return -ENOMEM; } INIT_WORK(&unsol->work, process_unsol_events); @@ -307,16 +315,15 @@ static void snd_hda_codec_free(struct hda_codec *codec); static int snd_hda_bus_free(struct hda_bus *bus) { - struct list_head *p, *n; + struct hda_codec *codec, *n; - if (! bus) + if (!bus) return 0; if (bus->unsol) { flush_scheduled_work(); kfree(bus->unsol); } - list_for_each_safe(p, n, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry_safe(codec, n, &bus->codec_list, list) { snd_hda_codec_free(codec); } if (bus->ops.private_free) @@ -370,7 +377,8 @@ int __devinit snd_hda_bus_new(struct snd_card *card, mutex_init(&bus->cmd_mutex); INIT_LIST_HEAD(&bus->codec_list); - if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) { + err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); + if (err < 0) { snd_hda_bus_free(bus); return err; } @@ -393,10 +401,10 @@ find_codec_preset(struct hda_codec *codec) for (tbl = hda_preset_tables; *tbl; tbl++) { for (preset = *tbl; preset->id; preset++) { u32 mask = preset->mask; - if (! mask) + if (!mask) mask = ~0; if (preset->id == (codec->vendor_id & mask) && - (! preset->rev || + (!preset->rev || preset->rev == codec->revision_id)) return preset; } @@ -421,14 +429,15 @@ void snd_hda_get_codec_name(struct hda_codec *codec, break; } } - if (! vendor) { + if (!vendor) { sprintf(tmp, "Generic %04x", vendor_id); vendor = tmp; } if (codec->preset && codec->preset->name) snprintf(name, namelen, "%s %s", vendor, codec->preset->name); else - snprintf(name, namelen, "%s ID %x", vendor, codec->vendor_id & 0xffff); + snprintf(name, namelen, "%s ID %x", vendor, + codec->vendor_id & 0xffff); } /* @@ -441,7 +450,9 @@ static void __devinit setup_fg_nodes(struct hda_codec *codec) total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); for (i = 0; i < total_nodes; i++, nid++) { - switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) { + unsigned int func; + func = snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE); + switch (func & 0xff) { case AC_GRP_AUDIO_FUNCTION: codec->afg = nid; break; @@ -465,7 +476,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node, &codec->start_nid); codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL); - if (! codec->wcaps) + if (!codec->wcaps) return -ENOMEM; nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) @@ -480,7 +491,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) */ static void snd_hda_codec_free(struct hda_codec *codec) { - if (! codec) + if (!codec) return; list_del(&codec->list); codec->bus->caddr_tbl[codec->addr] = NULL; @@ -512,7 +523,8 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL); if (bus->caddr_tbl[codec_addr]) { - snd_printk(KERN_ERR "hda_codec: address 0x%x is already occupied\n", codec_addr); + snd_printk(KERN_ERR "hda_codec: " + "address 0x%x is already occupied\n", codec_addr); return -EBUSY; } @@ -530,18 +542,21 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, list_add_tail(&codec->list, &bus->codec_list); bus->caddr_tbl[codec_addr] = codec; - codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); + codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, + AC_PAR_VENDOR_ID); if (codec->vendor_id == -1) /* read again, hopefully the access method was corrected * in the last read... */ codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); - codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); - codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); + codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, + AC_PAR_SUBSYSTEM_ID); + codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, + AC_PAR_REV_ID); setup_fg_nodes(codec); - if (! codec->afg && ! codec->mfg) { + if (!codec->afg && !codec->mfg) { snd_printdd("hda_codec: no AFG or MFG node found\n"); snd_hda_codec_free(codec); return -ENODEV; @@ -553,15 +568,15 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, return -ENOMEM; } - if (! codec->subsystem_id) { + if (!codec->subsystem_id) { hda_nid_t nid = codec->afg ? codec->afg : codec->mfg; - codec->subsystem_id = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_SUBSYSTEM_ID, - 0); + codec->subsystem_id = + snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_SUBSYSTEM_ID, 0); } codec->preset = find_codec_preset(codec); - if (! *bus->card->mixername) + if (!*bus->card->mixername) snd_hda_get_codec_name(codec, bus->card->mixername, sizeof(bus->card->mixername)); @@ -595,13 +610,15 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, * @channel_id: channel id to pass, zero based. * @format: stream format. */ -void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, +void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, + u32 stream_tag, int channel_id, int format) { - if (! nid) + if (!nid) return; - snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", + snd_printdd("hda_codec_setup_stream: " + "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", nid, stream_tag, channel_id, format); snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | channel_id); @@ -645,15 +662,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key) if (codec->num_amp_entries >= codec->amp_info_size) { /* reallocate the array */ int new_size = codec->amp_info_size + 64; - struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info), - GFP_KERNEL); - if (! new_info) { - snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n"); + struct hda_amp_info *new_info; + new_info = kcalloc(new_size, sizeof(struct hda_amp_info), + GFP_KERNEL); + if (!new_info) { + snd_printk(KERN_ERR "hda_codec: " + "can't malloc amp_info\n"); return NULL; } if (codec->amp_info) { memcpy(new_info, codec->amp_info, - codec->amp_info_size * sizeof(struct hda_amp_info)); + codec->amp_info_size * + sizeof(struct hda_amp_info)); kfree(codec->amp_info); } codec->amp_info_size = new_size; @@ -674,15 +694,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key) */ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) { - struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); + struct hda_amp_info *info; - if (! info) + info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); + if (!info) return 0; - if (! (info->status & INFO_AMP_CAPS)) { - if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) + if (!(info->status & INFO_AMP_CAPS)) { + if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) nid = codec->afg; - info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ? - AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); + info->amp_caps = snd_hda_param_read(codec, nid, + direction == HDA_OUTPUT ? + AC_PAR_AMP_OUT_CAP : + AC_PAR_AMP_IN_CAP); info->status |= INFO_AMP_CAPS; } return info->amp_caps; @@ -692,8 +715,9 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) * read the current volume to info * if the cache exists, read the cache value. */ -static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, - hda_nid_t nid, int ch, int direction, int index) +static unsigned int get_vol_mute(struct hda_codec *codec, + struct hda_amp_info *info, hda_nid_t nid, + int ch, int direction, int index) { u32 val, parm; @@ -703,7 +727,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; parm |= index; - val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm); + val = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, parm); info->vol[ch] = val & 0xff; info->status |= INFO_AMP_VOL(ch); return info->vol[ch]; @@ -713,7 +738,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i * write the current volume in info to the h/w and update the cache */ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, - hda_nid_t nid, int ch, int direction, int index, int val) + hda_nid_t nid, int ch, int direction, int index, + int val) { u32 parm; @@ -731,8 +757,9 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index) { - struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); - if (! info) + struct hda_amp_info *info; + info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); + if (!info) return 0; return get_vol_mute(codec, info, nid, ch, direction, index); } @@ -743,13 +770,14 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val) { - struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); + struct hda_amp_info *info; - if (! info) + info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); + if (!info) return 0; val &= mask; val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; - if (info->vol[ch] == val && ! codec->in_resume) + if (info->vol[ch] == val && !codec->in_resume) return 0; put_vol_mute(codec, info, nid, ch, direction, idx, val); return 1; @@ -766,7 +794,8 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) /* volume */ -int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); u16 nid = get_amp_nid(kcontrol); @@ -775,9 +804,11 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ u32 caps; caps = query_amp_caps(codec, nid, dir); - caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; /* num steps */ - if (! caps) { - printk(KERN_WARNING "hda_codec: num_steps = 0 for NID=0x%x\n", nid); + /* num steps */ + caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; + if (!caps) { + printk(KERN_WARNING "hda_codec: " + "num_steps = 0 for NID=0x%x\n", nid); return -EINVAL; } uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -787,7 +818,8 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 0; } -int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -803,7 +835,8 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e return 0; } -int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -835,7 +868,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, if (size < 4 * sizeof(unsigned int)) return -ENOMEM; caps = query_amp_caps(codec, nid, dir); - val2 = (((caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT) + 1) * 25; + val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT; + val2 = (val2 + 1) * 25; val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); val1 = ((int)val1) * ((int)val2); if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) @@ -850,7 +884,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, } /* switch */ -int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { int chs = get_amp_channels(kcontrol); @@ -861,7 +896,8 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 0; } -int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -871,13 +907,16 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e long *valp = ucontrol->value.integer.value; if (chs & 1) - *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80) ? 0 : 1; + *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & + 0x80) ? 0 : 1; if (chs & 2) - *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80) ? 0 : 1; + *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & + 0x80) ? 0 : 1; return 0; } -int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -908,7 +947,8 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e #define AMP_VAL_IDX_SHIFT 19 #define AMP_VAL_IDX_MASK (0x0f<<19) -int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); unsigned long pval; @@ -923,7 +963,8 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ return err; } -int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); unsigned long pval; @@ -933,7 +974,8 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ pval = kcontrol->private_value; indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; for (i = 0; i < indices; i++) { - kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT); + kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | + (i << AMP_VAL_IDX_SHIFT); err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); if (err < 0) break; @@ -948,14 +990,16 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ * SPDIF out controls */ -static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0; } -static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_NONAUDIO | @@ -966,7 +1010,8 @@ static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } -static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_NONAUDIO | @@ -974,7 +1019,8 @@ static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } -static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); @@ -994,19 +1040,21 @@ static unsigned short convert_from_spdif_status(unsigned int sbits) unsigned short val = 0; if (sbits & IEC958_AES0_PROFESSIONAL) - val |= 1 << 6; + val |= AC_DIG1_PROFESSIONAL; if (sbits & IEC958_AES0_NONAUDIO) - val |= 1 << 5; + val |= AC_DIG1_NONAUDIO; if (sbits & IEC958_AES0_PROFESSIONAL) { - if ((sbits & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015) - val |= 1 << 3; + if ((sbits & IEC958_AES0_PRO_EMPHASIS) == + IEC958_AES0_PRO_EMPHASIS_5015) + val |= AC_DIG1_EMPHASIS; } else { - if ((sbits & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015) - val |= 1 << 3; - if (! (sbits & IEC958_AES0_CON_NOT_COPYRIGHT)) - val |= 1 << 4; + if ((sbits & IEC958_AES0_CON_EMPHASIS) == + IEC958_AES0_CON_EMPHASIS_5015) + val |= AC_DIG1_EMPHASIS; + if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT)) + val |= AC_DIG1_COPYRIGHT; if (sbits & (IEC958_AES1_CON_ORIGINAL << 8)) - val |= 1 << 7; + val |= AC_DIG1_LEVEL; val |= sbits & (IEC958_AES1_CON_CATEGORY << 8); } return val; @@ -1018,26 +1066,27 @@ static unsigned int convert_to_spdif_status(unsigned short val) { unsigned int sbits = 0; - if (val & (1 << 5)) + if (val & AC_DIG1_NONAUDIO) sbits |= IEC958_AES0_NONAUDIO; - if (val & (1 << 6)) + if (val & AC_DIG1_PROFESSIONAL) sbits |= IEC958_AES0_PROFESSIONAL; if (sbits & IEC958_AES0_PROFESSIONAL) { - if (sbits & (1 << 3)) + if (sbits & AC_DIG1_EMPHASIS) sbits |= IEC958_AES0_PRO_EMPHASIS_5015; } else { - if (val & (1 << 3)) + if (val & AC_DIG1_EMPHASIS) sbits |= IEC958_AES0_CON_EMPHASIS_5015; - if (! (val & (1 << 4))) + if (!(val & AC_DIG1_COPYRIGHT)) sbits |= IEC958_AES0_CON_NOT_COPYRIGHT; - if (val & (1 << 7)) + if (val & AC_DIG1_LEVEL) sbits |= (IEC958_AES1_CON_ORIGINAL << 8); sbits |= val & (0x7f << 8); } return sbits; } -static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1055,15 +1104,18 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c codec->spdif_ctls = val; if (change || codec->in_resume) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + val & 0xff); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, + val >> 8); } mutex_unlock(&codec->spdif_mutex); return change; } -static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; @@ -1072,15 +1124,17 @@ static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct s return 0; } -static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = codec->spdif_ctls & 1; + ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE; return 0; } -static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1088,20 +1142,21 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn int change; mutex_lock(&codec->spdif_mutex); - val = codec->spdif_ctls & ~1; + val = codec->spdif_ctls & ~AC_DIG1_ENABLE; if (ucontrol->value.integer.value[0]) - val |= 1; + val |= AC_DIG1_ENABLE; change = codec->spdif_ctls != val; if (change || codec->in_resume) { codec->spdif_ctls = val; snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); - if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) + /* unmute amp switch (if any) */ + if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && + (val & AC_DIG1_ENABLE)) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | - AC_AMP_SET_OUTPUT | - ((val & 1) ? 0 : 0x80)); + AC_AMP_SET_OUTPUT); } mutex_unlock(&codec->spdif_mutex); return change; @@ -1159,10 +1214,12 @@ int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec, for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { kctl = snd_ctl_new1(dig_mix, codec); kctl->private_value = nid; - if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) + err = snd_ctl_add(codec->bus->card, kctl); + if (err < 0) return err; } - codec->spdif_ctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0); + codec->spdif_ctls = + snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0); codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); return 0; } @@ -1173,7 +1230,8 @@ int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec, #define snd_hda_spdif_in_switch_info snd_hda_spdif_out_switch_info -static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); @@ -1181,7 +1239,8 @@ static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd return 0; } -static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1192,13 +1251,15 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd change = codec->spdif_in_enable != val; if (change || codec->in_resume) { codec->spdif_in_enable = val; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + val); } mutex_unlock(&codec->spdif_mutex); return change; } -static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1252,10 +1313,13 @@ int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec, for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { kctl = snd_ctl_new1(dig_mix, codec); kctl->private_value = nid; - if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) + err = snd_ctl_add(codec->bus->card, kctl); + if (err < 0) return err; } - codec->spdif_in_enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & 1; + codec->spdif_in_enable = + snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & + AC_DIG1_ENABLE; return 0; } @@ -1295,13 +1359,12 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, */ int __devinit snd_hda_build_controls(struct hda_bus *bus) { - struct list_head *p; + struct hda_codec *codec; /* build controls */ - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { int err; - if (! codec->patch_ops.build_controls) + if (!codec->patch_ops.build_controls) continue; err = codec->patch_ops.build_controls(codec); if (err < 0) @@ -1309,13 +1372,12 @@ int __devinit snd_hda_build_controls(struct hda_bus *bus) } /* initialize */ - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { int err; hda_set_power_state(codec, codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); - if (! codec->patch_ops.init) + if (!codec->patch_ops.init) continue; err = codec->patch_ops.init(codec); if (err < 0) @@ -1381,7 +1443,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, val = rate_bits[i].hda_fmt; break; } - if (! rate_bits[i].hz) { + if (!rate_bits[i].hz) { snd_printdd("invalid rate %d\n", rate); return 0; } @@ -1406,7 +1468,8 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, val |= 0x20; break; default: - snd_printdd("invalid format width %d\n", snd_pcm_format_width(format)); + snd_printdd("invalid format width %d\n", + snd_pcm_format_width(format)); return 0; } @@ -1439,7 +1502,7 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, if (val == -1) return -EIO; } - if (! val) + if (!val) val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); if (ratesp) { @@ -1460,8 +1523,9 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); if (streams == -1) return -EIO; - if (! streams) { - streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); + if (!streams) { + streams = snd_hda_param_read(codec, codec->afg, + AC_PAR_STREAM); if (streams == -1) return -EIO; } @@ -1485,7 +1549,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, bps = 24; else if (val & AC_SUPPCM_BITS_20) bps = 20; - } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|AC_SUPPCM_BITS_32)) { + } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24| + AC_SUPPCM_BITS_32)) { formats |= SNDRV_PCM_FMTBIT_S32_LE; if (val & AC_SUPPCM_BITS_32) bps = 32; @@ -1495,10 +1560,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, bps = 20; } } - else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */ + else if (streams == AC_SUPFMT_FLOAT32) { + /* should be exclusive */ formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; bps = 32; - } else if (streams == AC_SUPFMT_AC3) { /* should be exclusive */ + } else if (streams == AC_SUPFMT_AC3) { + /* should be exclusive */ /* temporary hack: we have still no proper support * for the direct AC3 stream... */ @@ -1515,7 +1582,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, } /** - * snd_hda_is_supported_format - check whether the given node supports the format val + * snd_hda_is_supported_format - check whether the given node supports + * the format val * * Returns 1 if supported, 0 if not. */ @@ -1531,7 +1599,7 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, if (val == -1) return 0; } - if (! val) { + if (!val) { val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); if (val == -1) return 0; @@ -1550,31 +1618,31 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); if (stream == -1) return 0; - if (! stream && nid != codec->afg) + if (!stream && nid != codec->afg) stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); - if (! stream || stream == -1) + if (!stream || stream == -1) return 0; if (stream & AC_SUPFMT_PCM) { switch (format & 0xf0) { case 0x00: - if (! (val & AC_SUPPCM_BITS_8)) + if (!(val & AC_SUPPCM_BITS_8)) return 0; break; case 0x10: - if (! (val & AC_SUPPCM_BITS_16)) + if (!(val & AC_SUPPCM_BITS_16)) return 0; break; case 0x20: - if (! (val & AC_SUPPCM_BITS_20)) + if (!(val & AC_SUPPCM_BITS_20)) return 0; break; case 0x30: - if (! (val & AC_SUPPCM_BITS_24)) + if (!(val & AC_SUPPCM_BITS_24)) return 0; break; case 0x40: - if (! (val & AC_SUPPCM_BITS_32)) + if (!(val & AC_SUPPCM_BITS_32)) return 0; break; default: @@ -1615,15 +1683,15 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo, return 0; } -static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream *info) +static int __devinit set_pcm_default_values(struct hda_codec *codec, + struct hda_pcm_stream *info) { - if (info->nid) { - /* query support PCM information from the given NID */ - if (! info->rates || ! info->formats) - snd_hda_query_supported_pcm(codec, info->nid, - info->rates ? NULL : &info->rates, - info->formats ? NULL : &info->formats, - info->maxbps ? NULL : &info->maxbps); + /* query support PCM information from the given NID */ + if (info->nid && (!info->rates || !info->formats)) { + snd_hda_query_supported_pcm(codec, info->nid, + info->rates ? NULL : &info->rates, + info->formats ? NULL : &info->formats, + info->maxbps ? NULL : &info->maxbps); } if (info->ops.open == NULL) info->ops.open = hda_pcm_default_open_close; @@ -1668,13 +1736,12 @@ static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream */ int __devinit snd_hda_build_pcms(struct hda_bus *bus) { - struct list_head *p; + struct hda_codec *codec; - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { unsigned int pcm, s; int err; - if (! codec->patch_ops.build_pcms) + if (!codec->patch_ops.build_pcms) continue; err = codec->patch_ops.build_pcms(codec); if (err < 0) @@ -1683,7 +1750,7 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus) for (s = 0; s < 2; s++) { struct hda_pcm_stream *info; info = &codec->pcm_info[pcm].stream[s]; - if (! info->substreams) + if (!info->substreams) continue; err = set_pcm_default_values(codec, info); if (err < 0) @@ -1767,17 +1834,18 @@ int __devinit snd_hda_add_new_ctls(struct hda_codec *codec, for (; knew->name; knew++) { struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); - if (! kctl) + if (!kctl) return -ENOMEM; err = snd_ctl_add(codec->bus->card, kctl); if (err < 0) { - if (! codec->addr) + if (!codec->addr) return err; kctl = snd_ctl_new1(knew, codec); - if (! kctl) + if (!kctl) return -ENOMEM; kctl->id.device = codec->addr; - if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) + err = snd_ctl_add(codec->bus->card, kctl); + if (err < 0) return err; } } @@ -1788,8 +1856,10 @@ int __devinit snd_hda_add_new_ctls(struct hda_codec *codec, /* * Channel mode helper */ -int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, - const struct hda_channel_mode *chmode, int num_chmodes) +int snd_hda_ch_mode_info(struct hda_codec *codec, + struct snd_ctl_elem_info *uinfo, + const struct hda_channel_mode *chmode, + int num_chmodes) { uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -1801,8 +1871,10 @@ int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinf return 0; } -int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, - const struct hda_channel_mode *chmode, int num_chmodes, +int snd_hda_ch_mode_get(struct hda_codec *codec, + struct snd_ctl_elem_value *ucontrol, + const struct hda_channel_mode *chmode, + int num_chmodes, int max_channels) { int i; @@ -1816,15 +1888,17 @@ int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucon return 0; } -int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, - const struct hda_channel_mode *chmode, int num_chmodes, +int snd_hda_ch_mode_put(struct hda_codec *codec, + struct snd_ctl_elem_value *ucontrol, + const struct hda_channel_mode *chmode, + int num_chmodes, int *max_channelsp) { unsigned int mode; mode = ucontrol->value.enumerated.item[0]; snd_assert(mode < num_chmodes, return -EINVAL); - if (*max_channelsp == chmode[mode].channels && ! codec->in_resume) + if (*max_channelsp == chmode[mode].channels && !codec->in_resume) return 0; /* change the current channel setting */ *max_channelsp = chmode[mode].channels; @@ -1836,7 +1910,8 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucon /* * input MUX helper */ -int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo) +int snd_hda_input_mux_info(const struct hda_input_mux *imux, + struct snd_ctl_elem_info *uinfo) { unsigned int index; @@ -1850,8 +1925,10 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem return 0; } -int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, - struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, +int snd_hda_input_mux_put(struct hda_codec *codec, + const struct hda_input_mux *imux, + struct snd_ctl_elem_value *ucontrol, + hda_nid_t nid, unsigned int *cur_val) { unsigned int idx; @@ -1859,7 +1936,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, imux->items[idx].index); @@ -1890,7 +1967,8 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, /* * open the digital out in the exclusive mode */ -int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) +int snd_hda_multi_out_dig_open(struct hda_codec *codec, + struct hda_multi_out *mout) { mutex_lock(&codec->spdif_mutex); if (mout->dig_out_used == HDA_DIG_ANALOG_DUP) @@ -1916,7 +1994,8 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, /* * release the digital out */ -int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) +int snd_hda_multi_out_dig_close(struct hda_codec *codec, + struct hda_multi_out *mout) { mutex_lock(&codec->spdif_mutex); mout->dig_out_used = 0; @@ -1927,7 +2006,8 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *m /* * set up more restrictions for analog out */ -int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, +int snd_hda_multi_out_analog_open(struct hda_codec *codec, + struct hda_multi_out *mout, struct snd_pcm_substream *substream) { substream->runtime->hw.channels_max = mout->max_channels; @@ -1939,7 +2019,8 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out * set up the i/o for analog out * when the digital out is available, copy the front out to digital out, too. */ -int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, +int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, + struct hda_multi_out *mout, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream) @@ -1951,23 +2032,27 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o mutex_lock(&codec->spdif_mutex); if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { if (chs == 2 && - snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && - ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) { + snd_hda_is_supported_format(codec, mout->dig_out_nid, + format) && + !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { mout->dig_out_used = HDA_DIG_ANALOG_DUP; setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format); } else { mout->dig_out_used = 0; - snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); + snd_hda_codec_setup_stream(codec, mout->dig_out_nid, + 0, 0, 0); } } mutex_unlock(&codec->spdif_mutex); /* front */ - snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); + snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, + 0, format); if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]) /* headphone out will just decode front left/right (stereo) */ - snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); + snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, + 0, format); /* extra outputs copied from front */ for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) if (mout->extra_out_nid[i]) @@ -1978,11 +2063,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o /* surrounds */ for (i = 1; i < mout->num_dacs; i++) { if (chs >= (i + 1) * 2) /* independent out */ - snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2, - format); + snd_hda_codec_setup_stream(codec, nids[i], stream_tag, + i * 2, format); else /* copy front */ - snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0, - format); + snd_hda_codec_setup_stream(codec, nids[i], stream_tag, + 0, format); } return 0; } @@ -1990,7 +2075,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o /* * clean up the setting for analog out */ -int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout) +int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, + struct hda_multi_out *mout) { hda_nid_t *nids = mout->dac_nids; int i; @@ -2058,7 +2144,8 @@ int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); for (nid = nid_start; nid < nodes + nid_start; nid++) { unsigned int wid_caps = get_wcaps(codec, nid); - unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + unsigned int wid_type = + (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; unsigned int def_conf; short assoc, loc; @@ -2069,7 +2156,8 @@ int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, if (ignore_nids && is_in_nid_list(nid, ignore_nids)) continue; - def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); + def_conf = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) continue; loc = get_defcfg_location(def_conf); @@ -2077,9 +2165,9 @@ int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, case AC_JACK_LINE_OUT: seq = get_defcfg_sequence(def_conf); assoc = get_defcfg_association(def_conf); - if (! assoc) + if (!assoc) continue; - if (! assoc_line_out) + if (!assoc_line_out) assoc_line_out = assoc; else if (assoc_line_out != assoc) continue; @@ -2198,7 +2286,7 @@ int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, * FIX-UP: if no line-outs are detected, try to use speaker or HP pin * as a primary output */ - if (! cfg->line_outs) { + if (!cfg->line_outs) { if (cfg->speaker_outs) { cfg->line_outs = cfg->speaker_outs; memcpy(cfg->line_out_pins, cfg->speaker_pins, @@ -2237,11 +2325,10 @@ const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = { */ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) { - struct list_head *p; + struct hda_codec *codec; /* FIXME: should handle power widget capabilities */ - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { if (codec->patch_ops.suspend) codec->patch_ops.suspend(codec, state); hda_set_power_state(codec, @@ -2260,10 +2347,9 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) */ int snd_hda_resume(struct hda_bus *bus) { - struct list_head *p; + struct hda_codec *codec; - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { hda_set_power_state(codec, codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); @@ -2287,7 +2373,7 @@ int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) struct snd_ctl_elem_value *val; val = kmalloc(sizeof(*val), GFP_KERNEL); - if (! val) + if (!val) return -ENOMEM; codec->in_resume = 1; for (; knew->name; knew++) { -- cgit v0.10.2 From 826220463f619d14c5efea51aac6277b441052b8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 16 Apr 2007 12:32:52 +0200 Subject: [ALSA] Fix alsa-devel ML address Fixed MAINTAINERS, alsa-devel ML is now subscribers-only. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/MAINTAINERS b/MAINTAINERS index bd558ac..975f263 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -372,7 +372,7 @@ AOA (Apple Onboard Audio) ALSA DRIVER P: Johannes Berg M: johannes@sipsolutions.net L: linuxppc-dev@ozlabs.org -L: alsa-devel@alsa-project.org +L: alsa-devel@alsa-project.org (subscribers-only) S: Maintained APM DRIVER @@ -3239,13 +3239,13 @@ S: Maintained SOUND P: Jaroslav Kysela M: perex@suse.cz -L: alsa-devel@alsa-project.org +L: alsa-devel@alsa-project.org (subscribers-only) S: Maintained SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT P: Liam Girdwood M: liam.girdwood@wolfsonmicro.com -L: alsa-devel@alsa-project.org +L: alsa-devel@alsa-project.org (subscribers-only) S: Supported SPI SUBSYSTEM -- cgit v0.10.2 From 30652c4506c8bbfdf869ddc4c238e07de038f02a Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 16 Apr 2007 15:35:46 +0200 Subject: [ALSA] ASoC WM9712 kmemdup This patch creates the WM9712 codec register cache using kmemdup instead of doing a kzalloc followed by a memcpy. Signed-off-by: Graeme Gregory Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index ee7a691..264413a 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -676,14 +676,13 @@ static int wm9712_soc_probe(struct platform_device *pdev) codec = socdev->codec; mutex_init(&codec->mutex); - codec->reg_cache = - kzalloc(sizeof(u16) * ARRAY_SIZE(wm9712_reg), GFP_KERNEL); + codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL); + if (codec->reg_cache == NULL) { ret = -ENOMEM; goto cache_err; } - memcpy(codec->reg_cache, wm9712_reg, sizeof(u16) * ARRAY_SIZE(wm9712_reg)); - codec->reg_cache_size = sizeof(u16) * ARRAY_SIZE(wm9712_reg); + codec->reg_cache_size = sizeof(wm9712_reg); codec->reg_cache_step = 2; codec->name = "WM9712"; -- cgit v0.10.2 From 1e39221eba72e4af37b40e71749b0c18bb16b9a6 Mon Sep 17 00:00:00 2001 From: Seth Forshee Date: Mon, 16 Apr 2007 15:36:42 +0200 Subject: [ALSA] ASoC DAPM switching for reentrant codec paths This patch fixes an issue whereby power was applied to any inactive analog path that would leave and reenter a codec (e.g. ACOP -> ACIN on WM8753). This change now checks for such paths and DAPM will power them down when not in use. Signed-off-by: Seth Forshee Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 7caf8c7..96bce55 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -882,13 +882,15 @@ int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink, if (wsink->id == snd_soc_dapm_input) { if (wsource->id == snd_soc_dapm_micbias || wsource->id == snd_soc_dapm_mic || - wsink->id == snd_soc_dapm_line) + wsink->id == snd_soc_dapm_line || + wsink->id == snd_soc_dapm_output) wsink->ext = 1; } if (wsource->id == snd_soc_dapm_output) { if (wsink->id == snd_soc_dapm_spk || wsink->id == snd_soc_dapm_hp || - wsink->id == snd_soc_dapm_line) + wsink->id == snd_soc_dapm_line || + wsink->id == snd_soc_dapm_input) wsource->ext = 1; } -- cgit v0.10.2 From 36b8a8bbb402911e59acf13b5074eb8915e47a6a Mon Sep 17 00:00:00 2001 From: Frank Mandarino Date: Mon, 16 Apr 2007 17:18:52 +0200 Subject: [ALSA] ASoC AT91xxxx - SSC port DSP support This patch series by Frank Madarino updates the AT91xxxx core to add DSP/PCM audio hardware formats. Changes:- o Rename at19-i2s.c -> at91-ssc.c o Rename at91-i2s.h -> at91-ssc.h o Add DSP hardware formats. o Rename various I2S labels to SSC Signed-off-by: Frank Mandarino Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/at91/at91-i2s.c b/sound/soc/at91/at91-i2s.c deleted file mode 100644 index 9fc0c03..0000000 --- a/sound/soc/at91/at91-i2s.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * at91-i2s.c -- ALSA SoC I2S Audio Layer Platform driver - * - * Author: Frank Mandarino - * Endrelia Technologies Inc. - * - * Based on pxa2xx Platform drivers by - * Liam Girdwood - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "at91-pcm.h" -#include "at91-i2s.h" - -#if 0 -#define DBG(x...) printk(KERN_DEBUG "at91-i2s:" x) -#else -#define DBG(x...) -#endif - -#if defined(CONFIG_ARCH_AT91SAM9260) -#define NUM_SSC_DEVICES 1 -#else -#define NUM_SSC_DEVICES 3 -#endif - - -/* - * SSC PDC registers required by the PCM DMA engine. - */ -static struct at91_pdc_regs pdc_tx_reg = { - .xpr = ATMEL_PDC_TPR, - .xcr = ATMEL_PDC_TCR, - .xnpr = ATMEL_PDC_TNPR, - .xncr = ATMEL_PDC_TNCR, -}; - -static struct at91_pdc_regs pdc_rx_reg = { - .xpr = ATMEL_PDC_RPR, - .xcr = ATMEL_PDC_RCR, - .xnpr = ATMEL_PDC_RNPR, - .xncr = ATMEL_PDC_RNCR, -}; - -/* - * SSC & PDC status bits for transmit and receive. - */ -static struct at91_ssc_mask ssc_tx_mask = { - .ssc_enable = AT91_SSC_TXEN, - .ssc_disable = AT91_SSC_TXDIS, - .ssc_endx = AT91_SSC_ENDTX, - .ssc_endbuf = AT91_SSC_TXBUFE, - .pdc_enable = ATMEL_PDC_TXTEN, - .pdc_disable = ATMEL_PDC_TXTDIS, -}; - -static struct at91_ssc_mask ssc_rx_mask = { - .ssc_enable = AT91_SSC_RXEN, - .ssc_disable = AT91_SSC_RXDIS, - .ssc_endx = AT91_SSC_ENDRX, - .ssc_endbuf = AT91_SSC_RXBUFF, - .pdc_enable = ATMEL_PDC_RXTEN, - .pdc_disable = ATMEL_PDC_RXTDIS, -}; - - -/* - * DMA parameters. - */ -static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { - {{ - .name = "SSC0/I2S PCM Stereo out", - .pdc = &pdc_tx_reg, - .mask = &ssc_tx_mask, - }, - { - .name = "SSC0/I2S PCM Stereo in", - .pdc = &pdc_rx_reg, - .mask = &ssc_rx_mask, - }}, -#if NUM_SSC_DEVICES == 3 - {{ - .name = "SSC1/I2S PCM Stereo out", - .pdc = &pdc_tx_reg, - .mask = &ssc_tx_mask, - }, - { - .name = "SSC1/I2S PCM Stereo in", - .pdc = &pdc_rx_reg, - .mask = &ssc_rx_mask, - }}, - {{ - .name = "SSC2/I2S PCM Stereo out", - .pdc = &pdc_tx_reg, - .mask = &ssc_tx_mask, - }, - { - .name = "SSC1/I2S PCM Stereo in", - .pdc = &pdc_rx_reg, - .mask = &ssc_rx_mask, - }}, -#endif -}; - -struct at91_ssc_state { - u32 ssc_cmr; - u32 ssc_rcmr; - u32 ssc_rfmr; - u32 ssc_tcmr; - u32 ssc_tfmr; - u32 ssc_sr; - u32 ssc_imr; -}; - -static struct at91_ssc_info { - char *name; - struct at91_ssc_periph ssc; - spinlock_t lock; /* lock for dir_mask */ - unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */ - unsigned short initialized; /* 1=SSC has been initialized */ - unsigned short daifmt; - unsigned short cmr_div; - unsigned short tcmr_period; - unsigned short rcmr_period; - struct at91_pcm_dma_params *dma_params[2]; - struct at91_ssc_state ssc_state; - -} ssc_info[NUM_SSC_DEVICES] = { - { - .name = "ssc0", - .lock = SPIN_LOCK_UNLOCKED, - .dir_mask = 0, - .initialized = 0, - }, -#if NUM_SSC_DEVICES == 3 - { - .name = "ssc1", - .lock = SPIN_LOCK_UNLOCKED, - .dir_mask = 0, - .initialized = 0, - }, - { - .name = "ssc2", - .lock = SPIN_LOCK_UNLOCKED, - .dir_mask = 0, - .initialized = 0, - }, -#endif -}; - -static unsigned int at91_i2s_sysclk; - -/* - * SSC interrupt handler. Passes PDC interrupts to the DMA - * interrupt handler in the PCM driver. - */ -static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id) -{ - struct at91_ssc_info *ssc_p = dev_id; - struct at91_pcm_dma_params *dma_params; - u32 ssc_sr; - int i; - - ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR) - & at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR); - - /* - * Loop through the substreams attached to this SSC. If - * a DMA-related interrupt occurred on that substream, call - * the DMA interrupt handler function, if one has been - * registered in the dma_params structure by the PCM driver. - */ - for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) { - dma_params = ssc_p->dma_params[i]; - - if (dma_params != NULL && dma_params->dma_intr_handler != NULL && - (ssc_sr & - (dma_params->mask->ssc_endx | dma_params->mask->ssc_endbuf))) - - dma_params->dma_intr_handler(ssc_sr, dma_params->substream); - } - - return IRQ_HANDLED; -} - -/* - * Startup. Only that one substream allowed in each direction. - */ -static int at91_i2s_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; - int dir_mask; - - DBG("i2s_startup: SSC_SR=0x%08lx\n", - at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)); - dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2; - - spin_lock_irq(&ssc_p->lock); - if (ssc_p->dir_mask & dir_mask) { - spin_unlock_irq(&ssc_p->lock); - return -EBUSY; - } - ssc_p->dir_mask |= dir_mask; - spin_unlock_irq(&ssc_p->lock); - - return 0; -} - -/* - * Shutdown. Clear DMA parameters and shutdown the SSC if there - * are no other substreams open. - */ -static void at91_i2s_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; - struct at91_pcm_dma_params *dma_params; - int dir, dir_mask; - - dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; - dma_params = ssc_p->dma_params[dir]; - - if (dma_params != NULL) { - at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR, - dma_params->mask->ssc_disable); - DBG("%s disabled SSC_SR=0x%08lx\n", (dir ? "receive" : "transmit"), - at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)); - - dma_params->ssc_base = NULL; - dma_params->substream = NULL; - ssc_p->dma_params[dir] = NULL; - } - - dir_mask = 1 << dir; - - spin_lock_irq(&ssc_p->lock); - ssc_p->dir_mask &= ~dir_mask; - if (!ssc_p->dir_mask) { - /* Shutdown the SSC clock. */ - DBG("Stopping pid %d clock\n", ssc_p->ssc.pid); - at91_sys_write(AT91_PMC_PCDR, 1<ssc.pid); - - if (ssc_p->initialized) { - free_irq(ssc_p->ssc.pid, ssc_p); - ssc_p->initialized = 0; - } - - /* Reset the SSC */ - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST); - - /* Clear the SSC dividers */ - ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0; - } - spin_unlock_irq(&ssc_p->lock); -} - -/* - * Record the SSC system clock rate. - */ -static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - /* - * The only clock supplied to the SSC is the AT91 master clock, - * which is only used if the SSC is generating BCLK and/or - * LRC clocks. - */ - switch (clk_id) { - case AT91_SYSCLK_MCK: - at91_i2s_sysclk = freq; - break; - default: - return -EINVAL; - } - - return 0; -} - -/* - * Record the DAI format for use in hw_params(). - */ -static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, - unsigned int fmt) -{ - struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; - - if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S) - return -EINVAL; - - ssc_p->daifmt = fmt; - return 0; -} - -/* - * Record SSC clock dividers for use in hw_params(). - */ -static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, - int div_id, int div) -{ - struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; - - switch (div_id) { - case AT91SSC_CMR_DIV: - /* - * The same master clock divider is used for both - * transmit and receive, so if a value has already - * been set, it must match this value. - */ - if (ssc_p->cmr_div == 0) - ssc_p->cmr_div = div; - else - if (div != ssc_p->cmr_div) - return -EBUSY; - break; - - case AT91SSC_TCMR_PERIOD: - ssc_p->tcmr_period = div; - break; - - case AT91SSC_RCMR_PERIOD: - ssc_p->rcmr_period = div; - break; - - default: - return -EINVAL; - } - - return 0; -} - -/* - * Configure the SSC. - */ -static int at91_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - int id = rtd->dai->cpu_dai->id; - struct at91_ssc_info *ssc_p = &ssc_info[id]; - struct at91_pcm_dma_params *dma_params; - int dir, channels, bits; - u32 tfmr, rfmr, tcmr, rcmr; - int start_event; - int ret; - - /* - * Currently, there is only one set of dma params for - * each direction. If more are added, this code will - * have to be changed to select the proper set. - */ - dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; - - dma_params = &ssc_dma_params[id][dir]; - dma_params->ssc_base = ssc_p->ssc.base; - dma_params->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() - * function. It should not be used for other purposes - * as it is common to all substreams. - */ - rtd->dai->cpu_dai->dma_data = dma_params; - - channels = params_channels(params); - - /* - * The SSC only supports up to 16-bit samples in I2S format, due - * to the size of the Frame Mode Register FSLEN field. Also, I2S - * implies signed data. - */ - bits = 16; - dma_params->pdc_xfer_size = 2; - - /* - * Compute SSC register settings. - */ - switch (ssc_p->daifmt) { - case SND_SOC_DAIFMT_CBS_CFS: - /* - * SSC provides BCLK and LRC clocks. - * - * The SSC transmit and receive clocks are generated from the - * MCK divider, and the BCLK signal is output on the SSC TK line. - */ - rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD) - | (( 1 << 16) & AT91_SSC_STTDLY) - | (( AT91_SSC_START_FALLING_RF ) & AT91_SSC_START) - | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI) - | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO) - | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS); - - rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) - | (( AT91_SSC_FSOS_NEGATIVE ) & AT91_SSC_FSOS) - | (((bits - 1) << 16) & AT91_SSC_FSLEN) - | (((channels - 1) << 8) & AT91_SSC_DATNB) - | (( 1 << 7) & AT91_SSC_MSBF) - | (( 0 << 5) & AT91_SSC_LOOP) - | (((bits - 1) << 0) & AT91_SSC_DATALEN); - - tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD) - | (( 1 << 16) & AT91_SSC_STTDLY) - | (( AT91_SSC_START_FALLING_RF ) & AT91_SSC_START) - | (( AT91_SSC_CKI_FALLING ) & AT91_SSC_CKI) - | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO) - | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS); - - tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) - | (( 0 << 23) & AT91_SSC_FSDEN) - | (( AT91_SSC_FSOS_NEGATIVE ) & AT91_SSC_FSOS) - | (((bits - 1) << 16) & AT91_SSC_FSLEN) - | (((channels - 1) << 8) & AT91_SSC_DATNB) - | (( 1 << 7) & AT91_SSC_MSBF) - | (( 0 << 5) & AT91_SSC_DATDEF) - | (((bits - 1) << 0) & AT91_SSC_DATALEN); - break; - - case SND_SOC_DAIFMT_CBM_CFM: - - /* - * CODEC supplies BCLK and LRC clocks. - * - * The SSC transmit clock is obtained from the BCLK signal on - * on the TK line, and the SSC receive clock is generated from the - * transmit clock. - * - * For single channel data, one sample is transferred on the falling - * edge of the LRC clock. For two channel data, one sample is - * transferred on both edges of the LRC clock. - */ - start_event = channels == 1 - ? AT91_SSC_START_FALLING_RF - : AT91_SSC_START_EDGE_RF; - - rcmr = (( 0 << 24) & AT91_SSC_PERIOD) - | (( 1 << 16) & AT91_SSC_STTDLY) - | (( start_event ) & AT91_SSC_START) - | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI) - | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO) - | (( AT91_SSC_CKS_CLOCK ) & AT91_SSC_CKS); - - rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) - | (( AT91_SSC_FSOS_NONE ) & AT91_SSC_FSOS) - | (( 0 << 16) & AT91_SSC_FSLEN) - | (( 0 << 8) & AT91_SSC_DATNB) - | (( 1 << 7) & AT91_SSC_MSBF) - | (( 0 << 5) & AT91_SSC_LOOP) - | (((bits - 1) << 0) & AT91_SSC_DATALEN); - - tcmr = (( 0 << 24) & AT91_SSC_PERIOD) - | (( 1 << 16) & AT91_SSC_STTDLY) - | (( start_event ) & AT91_SSC_START) - | (( AT91_SSC_CKI_FALLING ) & AT91_SSC_CKI) - | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO) - | (( AT91_SSC_CKS_PIN ) & AT91_SSC_CKS); - - tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) - | (( 0 << 23) & AT91_SSC_FSDEN) - | (( AT91_SSC_FSOS_NONE ) & AT91_SSC_FSOS) - | (( 0 << 16) & AT91_SSC_FSLEN) - | (( 0 << 8) & AT91_SSC_DATNB) - | (( 1 << 7) & AT91_SSC_MSBF) - | (( 0 << 5) & AT91_SSC_DATDEF) - | (((bits - 1) << 0) & AT91_SSC_DATALEN); - break; - - case SND_SOC_DAIFMT_CBS_CFM: - case SND_SOC_DAIFMT_CBM_CFS: - default: - printk(KERN_WARNING "at91-i2s: unsupported DAI format 0x%x.\n", - ssc_p->daifmt); - return -EINVAL; - break; - } - DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr, rfmr, tcmr, tfmr); - - if (!ssc_p->initialized) { - - /* Enable PMC peripheral clock for this SSC */ - DBG("Starting pid %d clock\n", ssc_p->ssc.pid); - at91_sys_write(AT91_PMC_PCER, 1<ssc.pid); - - /* Reset the SSC and its PDC registers */ - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST); - - at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RPR, 0); - at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RCR, 0); - at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNPR, 0); - at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNCR, 0); - at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TPR, 0); - at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TCR, 0); - at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0); - at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0); - - if ((ret = request_irq(ssc_p->ssc.pid, at91_i2s_interrupt, - 0, ssc_p->name, ssc_p)) < 0) { - printk(KERN_WARNING "at91-i2s: request_irq failure\n"); - - DBG("Stopping pid %d clock\n", ssc_p->ssc.pid); - at91_sys_write(AT91_PMC_PCER, 1<ssc.pid); - return ret; - } - - ssc_p->initialized = 1; - } - - /* set SSC clock mode register */ - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->cmr_div); - - /* set receive clock mode and format */ - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, rcmr); - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, rfmr); - - /* set transmit clock mode and format */ - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, tcmr); - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, tfmr); - - DBG("hw_params: SSC initialized\n"); - return 0; -} - - -static int at91_i2s_prepare(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; - struct at91_pcm_dma_params *dma_params; - int dir; - - dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; - dma_params = ssc_p->dma_params[dir]; - - at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR, - dma_params->mask->ssc_enable); - - DBG("%s enabled SSC_SR=0x%08lx\n", dir ? "receive" : "transmit", - at91_ssc_read(dma_params->ssc_base + AT91_SSC_SR)); - return 0; -} - - -#ifdef CONFIG_PM -static int at91_i2s_suspend(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai) -{ - struct at91_ssc_info *ssc_p; - - if(!cpu_dai->active) - return 0; - - ssc_p = &ssc_info[cpu_dai->id]; - - /* Save the status register before disabling transmit and receive. */ - ssc_p->ssc_state.ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR); - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, - AT91_SSC_TXDIS | AT91_SSC_RXDIS); - - /* Save the current interrupt mask, then disable unmasked interrupts. */ - ssc_p->ssc_state.ssc_imr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR); - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IDR, ssc_p->ssc_state.ssc_imr); - - ssc_p->ssc_state.ssc_cmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_CMR); - ssc_p->ssc_state.ssc_rcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RCMR); - ssc_p->ssc_state.ssc_rfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RFMR); - ssc_p->ssc_state.ssc_tcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TCMR); - ssc_p->ssc_state.ssc_tfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TFMR); - - return 0; -} - -static int at91_i2s_resume(struct platform_device *pdev, - struct snd_soc_cpu_dai *cpu_dai) -{ - struct at91_ssc_info *ssc_p; - - if(!cpu_dai->active) - return 0; - - ssc_p = &ssc_info[cpu_dai->id]; - - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, ssc_p->ssc_state.ssc_tfmr); - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, ssc_p->ssc_state.ssc_tcmr); - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, ssc_p->ssc_state.ssc_rfmr); - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, ssc_p->ssc_state.ssc_rcmr); - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->ssc_state.ssc_cmr); - - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IER, ssc_p->ssc_state.ssc_imr); - - at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, - ((ssc_p->ssc_state.ssc_sr & AT91_SSC_RXENA) ? AT91_SSC_RXEN : 0) | - ((ssc_p->ssc_state.ssc_sr & AT91_SSC_TXENA) ? AT91_SSC_TXEN : 0)); - - return 0; -} - -#else -#define at91_i2s_suspend NULL -#define at91_i2s_resume NULL -#endif - -#define AT91_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ - SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ - SNDRV_PCM_RATE_96000) - -struct snd_soc_cpu_dai at91_i2s_dai[NUM_SSC_DEVICES] = { - { .name = "at91_ssc0/i2s", - .id = 0, - .type = SND_SOC_DAI_I2S, - .suspend = at91_i2s_suspend, - .resume = at91_i2s_resume, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .startup = at91_i2s_startup, - .shutdown = at91_i2s_shutdown, - .prepare = at91_i2s_prepare, - .hw_params = at91_i2s_hw_params,}, - .dai_ops = { - .set_sysclk = at91_i2s_set_dai_sysclk, - .set_fmt = at91_i2s_set_dai_fmt, - .set_clkdiv = at91_i2s_set_dai_clkdiv,}, - .private_data = &ssc_info[0].ssc, - }, -#if NUM_SSC_DEVICES == 3 - { .name = "at91_ssc1/i2s", - .id = 1, - .type = SND_SOC_DAI_I2S, - .suspend = at91_i2s_suspend, - .resume = at91_i2s_resume, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .startup = at91_i2s_startup, - .shutdown = at91_i2s_shutdown, - .prepare = at91_i2s_prepare, - .hw_params = at91_i2s_hw_params,}, - .dai_ops = { - .set_sysclk = at91_i2s_set_dai_sysclk, - .set_fmt = at91_i2s_set_dai_fmt, - .set_clkdiv = at91_i2s_set_dai_clkdiv,}, - .private_data = &ssc_info[1].ssc, - }, - { .name = "at91_ssc2/i2s", - .id = 2, - .type = SND_SOC_DAI_I2S, - .suspend = at91_i2s_suspend, - .resume = at91_i2s_resume, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = AT91_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = { - .startup = at91_i2s_startup, - .shutdown = at91_i2s_shutdown, - .prepare = at91_i2s_prepare, - .hw_params = at91_i2s_hw_params,}, - .dai_ops = { - .set_sysclk = at91_i2s_set_dai_sysclk, - .set_fmt = at91_i2s_set_dai_fmt, - .set_clkdiv = at91_i2s_set_dai_clkdiv,}, - .private_data = &ssc_info[2].ssc, - }, -#endif -}; - -EXPORT_SYMBOL_GPL(at91_i2s_dai); - -/* Module information */ -MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com"); -MODULE_DESCRIPTION("AT91 I2S ASoC Interface"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/at91/at91-i2s.h b/sound/soc/at91/at91-i2s.h deleted file mode 100644 index f8a875b..0000000 --- a/sound/soc/at91/at91-i2s.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * at91-i2s.h - ALSA I2S interface for the Atmel AT91 SoC - * - * Author: Frank Mandarino - * Endrelia Technologies Inc. - * Created: Jan 9, 2007 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _AT91_I2S_H -#define _AT91_I2S_H - -/* I2S system clock ids */ -#define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */ - -/* I2S divider ids */ -#define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */ -#define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */ -#define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */ - -extern struct snd_soc_cpu_dai at91_i2s_dai[]; - -#endif /* _AT91_I2S_H */ - diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c new file mode 100644 index 0000000..db1635a --- /dev/null +++ b/sound/soc/at91/at91-ssc.c @@ -0,0 +1,792 @@ +/* + * at91-ssc.c -- ALSA SoC AT91 SSC Audio Layer Platform driver + * + * Author: Frank Mandarino + * Endrelia Technologies Inc. + * + * Based on pxa2xx Platform drivers by + * Liam Girdwood + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "at91-pcm.h" +#include "at91-ssc.h" + +#if 0 +#define DBG(x...) printk(KERN_DEBUG "at91-ssc:" x) +#else +#define DBG(x...) +#endif + +#if defined(CONFIG_ARCH_AT91SAM9260) +#define NUM_SSC_DEVICES 1 +#else +#define NUM_SSC_DEVICES 3 +#endif + + +/* + * SSC PDC registers required by the PCM DMA engine. + */ +static struct at91_pdc_regs pdc_tx_reg = { + .xpr = ATMEL_PDC_TPR, + .xcr = ATMEL_PDC_TCR, + .xnpr = ATMEL_PDC_TNPR, + .xncr = ATMEL_PDC_TNCR, +}; + +static struct at91_pdc_regs pdc_rx_reg = { + .xpr = ATMEL_PDC_RPR, + .xcr = ATMEL_PDC_RCR, + .xnpr = ATMEL_PDC_RNPR, + .xncr = ATMEL_PDC_RNCR, +}; + +/* + * SSC & PDC status bits for transmit and receive. + */ +static struct at91_ssc_mask ssc_tx_mask = { + .ssc_enable = AT91_SSC_TXEN, + .ssc_disable = AT91_SSC_TXDIS, + .ssc_endx = AT91_SSC_ENDTX, + .ssc_endbuf = AT91_SSC_TXBUFE, + .pdc_enable = ATMEL_PDC_TXTEN, + .pdc_disable = ATMEL_PDC_TXTDIS, +}; + +static struct at91_ssc_mask ssc_rx_mask = { + .ssc_enable = AT91_SSC_RXEN, + .ssc_disable = AT91_SSC_RXDIS, + .ssc_endx = AT91_SSC_ENDRX, + .ssc_endbuf = AT91_SSC_RXBUFF, + .pdc_enable = ATMEL_PDC_RXTEN, + .pdc_disable = ATMEL_PDC_RXTDIS, +}; + + +/* + * DMA parameters. + */ +static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = { + {{ + .name = "SSC0 PCM out", + .pdc = &pdc_tx_reg, + .mask = &ssc_tx_mask, + }, + { + .name = "SSC0 PCM in", + .pdc = &pdc_rx_reg, + .mask = &ssc_rx_mask, + }}, +#if NUM_SSC_DEVICES == 3 + {{ + .name = "SSC1 PCM out", + .pdc = &pdc_tx_reg, + .mask = &ssc_tx_mask, + }, + { + .name = "SSC1 PCM in", + .pdc = &pdc_rx_reg, + .mask = &ssc_rx_mask, + }}, + {{ + .name = "SSC2 PCM out", + .pdc = &pdc_tx_reg, + .mask = &ssc_tx_mask, + }, + { + .name = "SSC2 PCM in", + .pdc = &pdc_rx_reg, + .mask = &ssc_rx_mask, + }}, +#endif +}; + +struct at91_ssc_state { + u32 ssc_cmr; + u32 ssc_rcmr; + u32 ssc_rfmr; + u32 ssc_tcmr; + u32 ssc_tfmr; + u32 ssc_sr; + u32 ssc_imr; +}; + +static struct at91_ssc_info { + char *name; + struct at91_ssc_periph ssc; + spinlock_t lock; /* lock for dir_mask */ + unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */ + unsigned short initialized; /* 1=SSC has been initialized */ + unsigned short daifmt; + unsigned short cmr_div; + unsigned short tcmr_period; + unsigned short rcmr_period; + struct at91_pcm_dma_params *dma_params[2]; + struct at91_ssc_state ssc_state; + +} ssc_info[NUM_SSC_DEVICES] = { + { + .name = "ssc0", + .lock = SPIN_LOCK_UNLOCKED, + .dir_mask = 0, + .initialized = 0, + }, +#if NUM_SSC_DEVICES == 3 + { + .name = "ssc1", + .lock = SPIN_LOCK_UNLOCKED, + .dir_mask = 0, + .initialized = 0, + }, + { + .name = "ssc2", + .lock = SPIN_LOCK_UNLOCKED, + .dir_mask = 0, + .initialized = 0, + }, +#endif +}; + +static unsigned int at91_ssc_sysclk; + +/* + * SSC interrupt handler. Passes PDC interrupts to the DMA + * interrupt handler in the PCM driver. + */ +static irqreturn_t at91_ssc_interrupt(int irq, void *dev_id) +{ + struct at91_ssc_info *ssc_p = dev_id; + struct at91_pcm_dma_params *dma_params; + u32 ssc_sr; + int i; + + ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR) + & at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR); + + /* + * Loop through the substreams attached to this SSC. If + * a DMA-related interrupt occurred on that substream, call + * the DMA interrupt handler function, if one has been + * registered in the dma_params structure by the PCM driver. + */ + for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) { + dma_params = ssc_p->dma_params[i]; + + if (dma_params != NULL && dma_params->dma_intr_handler != NULL && + (ssc_sr & + (dma_params->mask->ssc_endx | dma_params->mask->ssc_endbuf))) + + dma_params->dma_intr_handler(ssc_sr, dma_params->substream); + } + + return IRQ_HANDLED; +} + +/* + * Startup. Only that one substream allowed in each direction. + */ +static int at91_ssc_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; + int dir_mask; + + DBG("ssc_startup: SSC_SR=0x%08lx\n", + at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)); + dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2; + + spin_lock_irq(&ssc_p->lock); + if (ssc_p->dir_mask & dir_mask) { + spin_unlock_irq(&ssc_p->lock); + return -EBUSY; + } + ssc_p->dir_mask |= dir_mask; + spin_unlock_irq(&ssc_p->lock); + + return 0; +} + +/* + * Shutdown. Clear DMA parameters and shutdown the SSC if there + * are no other substreams open. + */ +static void at91_ssc_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; + struct at91_pcm_dma_params *dma_params; + int dir, dir_mask; + + dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; + dma_params = ssc_p->dma_params[dir]; + + if (dma_params != NULL) { + at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR, + dma_params->mask->ssc_disable); + DBG("%s disabled SSC_SR=0x%08lx\n", (dir ? "receive" : "transmit"), + at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)); + + dma_params->ssc_base = NULL; + dma_params->substream = NULL; + ssc_p->dma_params[dir] = NULL; + } + + dir_mask = 1 << dir; + + spin_lock_irq(&ssc_p->lock); + ssc_p->dir_mask &= ~dir_mask; + if (!ssc_p->dir_mask) { + /* Shutdown the SSC clock. */ + DBG("Stopping pid %d clock\n", ssc_p->ssc.pid); + at91_sys_write(AT91_PMC_PCDR, 1<ssc.pid); + + if (ssc_p->initialized) { + free_irq(ssc_p->ssc.pid, ssc_p); + ssc_p->initialized = 0; + } + + /* Reset the SSC */ + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST); + + /* Clear the SSC dividers */ + ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0; + } + spin_unlock_irq(&ssc_p->lock); +} + +/* + * Record the SSC system clock rate. + */ +static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + /* + * The only clock supplied to the SSC is the AT91 master clock, + * which is only used if the SSC is generating BCLK and/or + * LRC clocks. + */ + switch (clk_id) { + case AT91_SYSCLK_MCK: + at91_ssc_sysclk = freq; + break; + default: + return -EINVAL; + } + + return 0; +} + +/* + * Record the DAI format for use in hw_params(). + */ +static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai, + unsigned int fmt) +{ + struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; + + ssc_p->daifmt = fmt; + return 0; +} + +/* + * Record SSC clock dividers for use in hw_params(). + */ +static int at91_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai, + int div_id, int div) +{ + struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id]; + + switch (div_id) { + case AT91SSC_CMR_DIV: + /* + * The same master clock divider is used for both + * transmit and receive, so if a value has already + * been set, it must match this value. + */ + if (ssc_p->cmr_div == 0) + ssc_p->cmr_div = div; + else + if (div != ssc_p->cmr_div) + return -EBUSY; + break; + + case AT91SSC_TCMR_PERIOD: + ssc_p->tcmr_period = div; + break; + + case AT91SSC_RCMR_PERIOD: + ssc_p->rcmr_period = div; + break; + + default: + return -EINVAL; + } + + return 0; +} + +/* + * Configure the SSC. + */ +static int at91_ssc_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + int id = rtd->dai->cpu_dai->id; + struct at91_ssc_info *ssc_p = &ssc_info[id]; + struct at91_pcm_dma_params *dma_params; + int dir, channels, bits; + u32 tfmr, rfmr, tcmr, rcmr; + int start_event; + int ret; + + /* + * Currently, there is only one set of dma params for + * each direction. If more are added, this code will + * have to be changed to select the proper set. + */ + dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; + + dma_params = &ssc_dma_params[id][dir]; + dma_params->ssc_base = ssc_p->ssc.base; + dma_params->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() + * function. It should not be used for other purposes + * as it is common to all substreams. + */ + rtd->dai->cpu_dai->dma_data = dma_params; + + channels = params_channels(params); + + /* + * Determine sample size in bits and the PDC increment. + */ + switch(params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + bits = 8; + dma_params->pdc_xfer_size = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + bits = 16; + dma_params->pdc_xfer_size = 2; + break; + case SNDRV_PCM_FORMAT_S24_LE: + bits = 24; + dma_params->pdc_xfer_size = 4; + break; + case SNDRV_PCM_FORMAT_S32_LE: + bits = 32; + dma_params->pdc_xfer_size = 4; + break; + default: + printk(KERN_WARNING "at91-ssc: unsupported PCM format"); + return -EINVAL; + } + + /* + * The SSC only supports up to 16-bit samples in I2S format, due + * to the size of the Frame Mode Register FSLEN field. + */ + if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S + && bits > 16) { + printk(KERN_WARNING + "at91-ssc: sample size %d is too large for I2S\n", bits); + return -EINVAL; + } + + /* + * Compute SSC register settings. + */ + switch (ssc_p->daifmt + & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) { + + case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS: + /* + * I2S format, SSC provides BCLK and LRC clocks. + * + * The SSC transmit and receive clocks are generated from the + * MCK divider, and the BCLK signal is output on the SSC TK line. + */ + rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD) + | (( 1 << 16) & AT91_SSC_STTDLY) + | (( AT91_SSC_START_FALLING_RF ) & AT91_SSC_START) + | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI) + | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO) + | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS); + + rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) + | (( AT91_SSC_FSOS_NEGATIVE ) & AT91_SSC_FSOS) + | (((bits - 1) << 16) & AT91_SSC_FSLEN) + | (((channels - 1) << 8) & AT91_SSC_DATNB) + | (( 1 << 7) & AT91_SSC_MSBF) + | (( 0 << 5) & AT91_SSC_LOOP) + | (((bits - 1) << 0) & AT91_SSC_DATALEN); + + tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD) + | (( 1 << 16) & AT91_SSC_STTDLY) + | (( AT91_SSC_START_FALLING_RF ) & AT91_SSC_START) + | (( AT91_SSC_CKI_FALLING ) & AT91_SSC_CKI) + | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO) + | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS); + + tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) + | (( 0 << 23) & AT91_SSC_FSDEN) + | (( AT91_SSC_FSOS_NEGATIVE ) & AT91_SSC_FSOS) + | (((bits - 1) << 16) & AT91_SSC_FSLEN) + | (((channels - 1) << 8) & AT91_SSC_DATNB) + | (( 1 << 7) & AT91_SSC_MSBF) + | (( 0 << 5) & AT91_SSC_DATDEF) + | (((bits - 1) << 0) & AT91_SSC_DATALEN); + break; + + case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM: + /* + * I2S format, CODEC supplies BCLK and LRC clocks. + * + * The SSC transmit clock is obtained from the BCLK signal on + * on the TK line, and the SSC receive clock is generated from the + * transmit clock. + * + * For single channel data, one sample is transferred on the falling + * edge of the LRC clock. For two channel data, one sample is + * transferred on both edges of the LRC clock. + */ + start_event = channels == 1 + ? AT91_SSC_START_FALLING_RF + : AT91_SSC_START_EDGE_RF; + + rcmr = (( 0 << 24) & AT91_SSC_PERIOD) + | (( 1 << 16) & AT91_SSC_STTDLY) + | (( start_event ) & AT91_SSC_START) + | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI) + | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO) + | (( AT91_SSC_CKS_CLOCK ) & AT91_SSC_CKS); + + rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) + | (( AT91_SSC_FSOS_NONE ) & AT91_SSC_FSOS) + | (( 0 << 16) & AT91_SSC_FSLEN) + | (( 0 << 8) & AT91_SSC_DATNB) + | (( 1 << 7) & AT91_SSC_MSBF) + | (( 0 << 5) & AT91_SSC_LOOP) + | (((bits - 1) << 0) & AT91_SSC_DATALEN); + + tcmr = (( 0 << 24) & AT91_SSC_PERIOD) + | (( 1 << 16) & AT91_SSC_STTDLY) + | (( start_event ) & AT91_SSC_START) + | (( AT91_SSC_CKI_FALLING ) & AT91_SSC_CKI) + | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO) + | (( AT91_SSC_CKS_PIN ) & AT91_SSC_CKS); + + tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) + | (( 0 << 23) & AT91_SSC_FSDEN) + | (( AT91_SSC_FSOS_NONE ) & AT91_SSC_FSOS) + | (( 0 << 16) & AT91_SSC_FSLEN) + | (( 0 << 8) & AT91_SSC_DATNB) + | (( 1 << 7) & AT91_SSC_MSBF) + | (( 0 << 5) & AT91_SSC_DATDEF) + | (((bits - 1) << 0) & AT91_SSC_DATALEN); + break; + + case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS: + /* + * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks. + * + * The SSC transmit and receive clocks are generated from the + * MCK divider, and the BCLK signal is output on the SSC TK line. + */ + rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD) + | (( 1 << 16) & AT91_SSC_STTDLY) + | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START) + | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI) + | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO) + | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS); + + rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) + | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS) + | (( 0 << 16) & AT91_SSC_FSLEN) + | (((channels - 1) << 8) & AT91_SSC_DATNB) + | (( 1 << 7) & AT91_SSC_MSBF) + | (( 0 << 5) & AT91_SSC_LOOP) + | (((bits - 1) << 0) & AT91_SSC_DATALEN); + + tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD) + | (( 1 << 16) & AT91_SSC_STTDLY) + | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START) + | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI) + | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO) + | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS); + + tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE) + | (( 0 << 23) & AT91_SSC_FSDEN) + | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS) + | (( 0 << 16) & AT91_SSC_FSLEN) + | (((channels - 1) << 8) & AT91_SSC_DATNB) + | (( 1 << 7) & AT91_SSC_MSBF) + | (( 0 << 5) & AT91_SSC_DATDEF) + | (((bits - 1) << 0) & AT91_SSC_DATALEN); + + + + break; + + case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: + default: + printk(KERN_WARNING "at91-ssc: unsupported DAI format 0x%x.\n", + ssc_p->daifmt); + return -EINVAL; + break; + } + DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr, rfmr, tcmr, tfmr); + + if (!ssc_p->initialized) { + + /* Enable PMC peripheral clock for this SSC */ + DBG("Starting pid %d clock\n", ssc_p->ssc.pid); + at91_sys_write(AT91_PMC_PCER, 1<ssc.pid); + + /* Reset the SSC and its PDC registers */ + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST); + + at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RPR, 0); + at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RCR, 0); + at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNPR, 0); + at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNCR, 0); + at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TPR, 0); + at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TCR, 0); + at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0); + at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0); + + if ((ret = request_irq(ssc_p->ssc.pid, at91_ssc_interrupt, + 0, ssc_p->name, ssc_p)) < 0) { + printk(KERN_WARNING "at91-ssc: request_irq failure\n"); + + DBG("Stopping pid %d clock\n", ssc_p->ssc.pid); + at91_sys_write(AT91_PMC_PCER, 1<ssc.pid); + return ret; + } + + ssc_p->initialized = 1; + } + + /* set SSC clock mode register */ + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->cmr_div); + + /* set receive clock mode and format */ + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, rcmr); + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, rfmr); + + /* set transmit clock mode and format */ + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, tcmr); + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, tfmr); + + DBG("hw_params: SSC initialized\n"); + return 0; +} + + +static int at91_ssc_prepare(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id]; + struct at91_pcm_dma_params *dma_params; + int dir; + + dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; + dma_params = ssc_p->dma_params[dir]; + + at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR, + dma_params->mask->ssc_enable); + + DBG("%s enabled SSC_SR=0x%08lx\n", dir ? "receive" : "transmit", + at91_ssc_read(dma_params->ssc_base + AT91_SSC_SR)); + return 0; +} + + +#ifdef CONFIG_PM +static int at91_ssc_suspend(struct platform_device *pdev, + struct snd_soc_cpu_dai *cpu_dai) +{ + struct at91_ssc_info *ssc_p; + + if(!cpu_dai->active) + return 0; + + ssc_p = &ssc_info[cpu_dai->id]; + + /* Save the status register before disabling transmit and receive. */ + ssc_p->ssc_state.ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR); + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, + AT91_SSC_TXDIS | AT91_SSC_RXDIS); + + /* Save the current interrupt mask, then disable unmasked interrupts. */ + ssc_p->ssc_state.ssc_imr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR); + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IDR, ssc_p->ssc_state.ssc_imr); + + ssc_p->ssc_state.ssc_cmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_CMR); + ssc_p->ssc_state.ssc_rcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RCMR); + ssc_p->ssc_state.ssc_rfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RFMR); + ssc_p->ssc_state.ssc_tcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TCMR); + ssc_p->ssc_state.ssc_tfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TFMR); + + return 0; +} + +static int at91_ssc_resume(struct platform_device *pdev, + struct snd_soc_cpu_dai *cpu_dai) +{ + struct at91_ssc_info *ssc_p; + + if(!cpu_dai->active) + return 0; + + ssc_p = &ssc_info[cpu_dai->id]; + + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, ssc_p->ssc_state.ssc_tfmr); + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, ssc_p->ssc_state.ssc_tcmr); + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, ssc_p->ssc_state.ssc_rfmr); + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, ssc_p->ssc_state.ssc_rcmr); + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->ssc_state.ssc_cmr); + + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IER, ssc_p->ssc_state.ssc_imr); + + at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, + ((ssc_p->ssc_state.ssc_sr & AT91_SSC_RXENA) ? AT91_SSC_RXEN : 0) | + ((ssc_p->ssc_state.ssc_sr & AT91_SSC_TXENA) ? AT91_SSC_TXEN : 0)); + + return 0; +} + +#else +#define at91_ssc_suspend NULL +#define at91_ssc_resume NULL +#endif + +#define AT91_SSC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000) + +#define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +struct snd_soc_cpu_dai at91_ssc_dai[NUM_SSC_DEVICES] = { + { .name = "at91-ssc0", + .id = 0, + .type = SND_SOC_DAI_PCM, + .suspend = at91_ssc_suspend, + .resume = at91_ssc_resume, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, + .ops = { + .startup = at91_ssc_startup, + .shutdown = at91_ssc_shutdown, + .prepare = at91_ssc_prepare, + .hw_params = at91_ssc_hw_params,}, + .dai_ops = { + .set_sysclk = at91_ssc_set_dai_sysclk, + .set_fmt = at91_ssc_set_dai_fmt, + .set_clkdiv = at91_ssc_set_dai_clkdiv,}, + .private_data = &ssc_info[0].ssc, + }, +#if NUM_SSC_DEVICES == 3 + { .name = "at91-ssc1", + .id = 1, + .type = SND_SOC_DAI_PCM, + .suspend = at91_ssc_suspend, + .resume = at91_ssc_resume, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, + .ops = { + .startup = at91_ssc_startup, + .shutdown = at91_ssc_shutdown, + .prepare = at91_ssc_prepare, + .hw_params = at91_ssc_hw_params,}, + .dai_ops = { + .set_sysclk = at91_ssc_set_dai_sysclk, + .set_fmt = at91_ssc_set_dai_fmt, + .set_clkdiv = at91_ssc_set_dai_clkdiv,}, + .private_data = &ssc_info[1].ssc, + }, + { .name = "at91-ssc2", + .id = 2, + .type = SND_SOC_DAI_PCM, + .suspend = at91_ssc_suspend, + .resume = at91_ssc_resume, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = AT91_SSC_RATES, + .formats = AT91_SSC_FORMATS,}, + .ops = { + .startup = at91_ssc_startup, + .shutdown = at91_ssc_shutdown, + .prepare = at91_ssc_prepare, + .hw_params = at91_ssc_hw_params,}, + .dai_ops = { + .set_sysclk = at91_ssc_set_dai_sysclk, + .set_fmt = at91_ssc_set_dai_fmt, + .set_clkdiv = at91_ssc_set_dai_clkdiv,}, + .private_data = &ssc_info[2].ssc, + }, +#endif +}; + +EXPORT_SYMBOL_GPL(at91_ssc_dai); + +/* Module information */ +MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com"); +MODULE_DESCRIPTION("AT91 SSC ASoC Interface"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/at91/at91-ssc.h b/sound/soc/at91/at91-ssc.h new file mode 100644 index 0000000..b188f97 --- /dev/null +++ b/sound/soc/at91/at91-ssc.h @@ -0,0 +1,27 @@ +/* + * at91-ssc.h - ALSA SSC interface for the Atmel AT91 SoC + * + * Author: Frank Mandarino + * Endrelia Technologies Inc. + * Created: Jan 9, 2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _AT91_SSC_H +#define _AT91_SSC_H + +/* SSC system clock ids */ +#define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */ + +/* SSC divider ids */ +#define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */ +#define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */ +#define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */ + +extern struct snd_soc_cpu_dai at91_ssc_dai[]; + +#endif /* _AT91_SSC_H */ + -- cgit v0.10.2 From eb831da553d1526b9acd5ee4cd83ff52ae446c5f Mon Sep 17 00:00:00 2001 From: Frank Mandarino Date: Mon, 16 Apr 2007 17:19:42 +0200 Subject: [ALSA] ASoC AT91xxxx eti B1 machine SSC changes This patch by Frank Madarino updates the eti B1 machine to use the newer AT91xxxx SSC core with the DSP/PCM audio hardware changes. Changes:- o #include 'at91-ssc.h' instead of 'at91-i2s.h' o Rename various I2S labels to SSC Signed-off-by: Frank Mandarino Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c index 8179df3..820a676 100644 --- a/sound/soc/at91/eti_b1_wm8731.c +++ b/sound/soc/at91/eti_b1_wm8731.c @@ -40,7 +40,7 @@ #include "../codecs/wm8731.h" #include "at91-pcm.h" -#include "at91-i2s.h" +#include "at91-ssc.h" #if 0 #define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x) @@ -248,15 +248,15 @@ static int eti_b1_wm8731_init(struct snd_soc_codec *codec) static struct snd_soc_dai_link eti_b1_dai = { .name = "WM8731", - .stream_name = "WM8731", - .cpu_dai = &at91_i2s_dai[1], + .stream_name = "WM8731 PCM", + .cpu_dai = &at91_ssc_dai[1], .codec_dai = &wm8731_dai, .init = eti_b1_wm8731_init, .ops = &eti_b1_ops, }; static struct snd_soc_machine snd_soc_machine_eti_b1 = { - .name = "ETI_B1", + .name = "ETI_B1_WM8731", .dai_link = &eti_b1_dai, .num_links = 1, }; -- cgit v0.10.2 From 1a236566ea320a05f3892d8dedd4b5c6bff8706b Mon Sep 17 00:00:00 2001 From: Frank Mandarino Date: Mon, 16 Apr 2007 17:20:09 +0200 Subject: [ALSA] ASoC AT91xxxx build fix This patch by Frank Madarino updates the AT91xxxx Makefile and Kconfig to build the renamed SSC files. Changes:- o Rename various i2s labels to ssc Signed-off-by: Frank Mandarino Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig index e41e75e..5cb93fd 100644 --- a/sound/soc/at91/Kconfig +++ b/sound/soc/at91/Kconfig @@ -6,13 +6,13 @@ config SND_AT91_SOC the AT91 SSC interface. You will also need to select the audio interfaces to support below. -config SND_AT91_SOC_I2S +config SND_AT91_SOC_SSC tristate config SND_AT91_SOC_ETI_B1_WM8731 - tristate "SoC I2S Audio support for WM8731-based Endrelia ETI-B1 boards" + tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards" depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1) - select SND_AT91_SOC_I2S + select SND_AT91_SOC_SSC select SND_SOC_WM8731 help Say Y if you want to add support for SoC audio on WM8731-based diff --git a/sound/soc/at91/Makefile b/sound/soc/at91/Makefile index b77b01a..f23da17 100644 --- a/sound/soc/at91/Makefile +++ b/sound/soc/at91/Makefile @@ -1,9 +1,9 @@ # AT91 Platform Support snd-soc-at91-objs := at91-pcm.o -snd-soc-at91-i2s-objs := at91-i2s.o +snd-soc-at91-ssc-objs := at91-ssc.o obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o -obj-$(CONFIG_SND_AT91_SOC_I2S) += snd-soc-at91-i2s.o +obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o # AT91 Machine Support snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o -- cgit v0.10.2 From 1f53aee0e0b398bad0c6ec2cd5ca2bccd4fbd56b Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 16 Apr 2007 19:17:44 +0200 Subject: [ALSA] SoC WM8753 codec support This patch series adds support for the WM8753 codec as found on the OpenMoko Neo 1973 (other Neo 1973 and Samsung S3C24xx patches to follow today) as well other new devices. Features:- o HiFi and Voice DAI supported (inc runtime switching of DAI mode) o DAPM o All mixers o PLL calculator o 16,20 and 24bit samples. o WM8753 I2C ID added to include/linux/i2c-id.h From: Liam Girdwood Signed-off-by: Harald Welte Signed-off-by: Graeme Gregory Signed-off-by: Seth Forshee Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 0e8da68..aa83d41 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -117,6 +117,7 @@ #define I2C_DRIVERID_ISL1208 88 /* Intersil ISL1208 RTC */ #define I2C_DRIVERID_WM8731 89 /* Wolfson WM8731 audio codec */ #define I2C_DRIVERID_WM8750 90 /* Wolfson WM8750 audio codec */ +#define I2C_DRIVERID_WM8753 91 /* Wolfson WM8753 audio codec */ #define I2C_DRIVERID_I2CDEV 900 #define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */ diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c new file mode 100644 index 0000000..efced93 --- /dev/null +++ b/sound/soc/codecs/wm8753.c @@ -0,0 +1,1811 @@ +/* + * wm8753.c -- WM8753 ALSA Soc Audio driver + * + * Copyright 2003 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Notes: + * The WM8753 is a low power, high quality stereo codec with integrated PCM + * codec designed for portable digital telephony applications. + * + * Dual DAI:- + * + * This driver support 2 DAI PCM's. This makes the default PCM available for + * HiFi audio (e.g. MP3, ogg) playback/capture and the other PCM available for + * voice. + * + * Please note that the voice PCM can be connected directly to a Bluetooth + * codec or GSM modem and thus cannot be read or written to, although it is + * available to be configured with snd_hw_params(), etc and kcontrols in the + * normal alsa manner. + * + * Fast DAI switching:- + * + * The driver can now fast switch between the DAI configurations via a + * an alsa kcontrol. This allows the PCM to remain open. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm8753.h" + +#define AUDIO_NAME "wm8753" +#define WM8753_VERSION "0.16" + +/* + * Debug + */ + +#define WM8753_DEBUG 0 + +#ifdef WM8753_DEBUG +#define dbg(format, arg...) \ + printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg) +#else +#define dbg(format, arg...) do {} while (0) +#endif +#define err(format, arg...) \ + printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg) +#define info(format, arg...) \ + printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg) +#define warn(format, arg...) \ + printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg) + +static int caps_charge = 2000; +module_param(caps_charge, int, 0); +MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)"); + +static void wm8753_set_dai_mode(struct snd_soc_codec *codec, + unsigned int mode); + +/* codec private data */ +struct wm8753_priv { + unsigned int sysclk; + unsigned int pcmclk; +}; + +/* + * wm8753 register cache + * We can't read the WM8753 register space when we + * are using 2 wire for device control, so we cache them instead. + */ +static const u16 wm8753_reg[] = { + 0x0008, 0x0000, 0x000a, 0x000a, + 0x0033, 0x0000, 0x0007, 0x00ff, + 0x00ff, 0x000f, 0x000f, 0x007b, + 0x0000, 0x0032, 0x0000, 0x00c3, + 0x00c3, 0x00c0, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0055, + 0x0005, 0x0050, 0x0055, 0x0050, + 0x0055, 0x0050, 0x0055, 0x0079, + 0x0079, 0x0079, 0x0079, 0x0079, + 0x0000, 0x0000, 0x0000, 0x0000, + 0x0097, 0x0097, 0x0000, 0x0004, + 0x0000, 0x0083, 0x0024, 0x01ba, + 0x0000, 0x0083, 0x0024, 0x01ba, + 0x0000, 0x0000 +}; + +/* + * read wm8753 register cache + */ +static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec, + unsigned int reg) +{ + u16 *cache = codec->reg_cache; + if (reg < 1 || reg > (ARRAY_SIZE(wm8753_reg) + 1)) + return -1; + return cache[reg - 1]; +} + +/* + * write wm8753 register cache + */ +static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + u16 *cache = codec->reg_cache; + if (reg < 1 || reg > 0x3f) + return; + cache[reg - 1] = value; +} + +/* + * write to the WM8753 register space + */ +static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + u8 data[2]; + + /* data is + * D15..D9 WM8753 register offset + * D8...D0 register data + */ + data[0] = (reg << 1) | ((value >> 8) & 0x0001); + data[1] = value & 0x00ff; + + wm8753_write_reg_cache (codec, reg, value); + if (codec->hw_write(codec->control_data, data, 2) == 2) + return 0; + else + return -EIO; +} + +#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0) + +/* + * WM8753 Controls + */ +static const char *wm8753_base[] = {"Linear Control", "Adaptive Boost"}; +static const char *wm8753_base_filter[] = + {"130Hz @ 48kHz", "200Hz @ 48kHz", "100Hz @ 16kHz", "400Hz @ 48kHz", + "100Hz @ 8kHz", "200Hz @ 8kHz"}; +static const char *wm8753_treble[] = {"8kHz", "4kHz"}; +static const char *wm8753_alc_func[] = {"Off", "Right", "Left", "Stereo"}; +static const char *wm8753_ng_type[] = {"Constant PGA Gain", "Mute ADC Output"}; +static const char *wm8753_3d_func[] = {"Capture", "Playback"}; +static const char *wm8753_3d_uc[] = {"2.2kHz", "1.5kHz"}; +static const char *wm8753_3d_lc[] = {"200Hz", "500Hz"}; +static const char *wm8753_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz"}; +static const char *wm8753_mono_mix[] = {"Stereo", "Left", "Right", "Mono"}; +static const char *wm8753_dac_phase[] = {"Non Inverted", "Inverted"}; +static const char *wm8753_line_mix[] = {"Line 1 + 2", "Line 1 - 2", + "Line 1", "Line 2"}; +static const char *wm8753_mono_mux[] = {"Line Mix", "Rx Mix"}; +static const char *wm8753_right_mux[] = {"Line 2", "Rx Mix"}; +static const char *wm8753_left_mux[] = {"Line 1", "Rx Mix"}; +static const char *wm8753_rxmsel[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"}; +static const char *wm8753_sidetone_mux[] = {"Left PGA", "Mic 1", "Mic 2", + "Right PGA"}; +static const char *wm8753_mono2_src[] = {"Inverted Mono 1", "Left", "Right", + "Left + Right"}; +static const char *wm8753_out3[] = {"VREF", "ROUT2", "Left + Right"}; +static const char *wm8753_out4[] = {"VREF", "Capture ST", "LOUT2"}; +static const char *wm8753_radcsel[] = {"PGA", "Line or RXP-RXN", "Sidetone"}; +static const char *wm8753_ladcsel[] = {"PGA", "Line or RXP-RXN", "Line"}; +static const char *wm8753_mono_adc[] = {"Stereo", "Analogue Mix Left", + "Analogue Mix Right", "Digital Mono Mix"}; +static const char *wm8753_adc_hp[] = {"3.4Hz @ 48kHz", "82Hz @ 16k", + "82Hz @ 8kHz", "170Hz @ 8kHz"}; +static const char *wm8753_adc_filter[] = {"HiFi", "Voice"}; +static const char *wm8753_mic_sel[] = {"Mic 1", "Mic 2", "Mic 3"}; +static const char *wm8753_dai_mode[] = {"DAI 0", "DAI 1", "DAI 2", "DAI 3"}; +static const char *wm8753_dat_sel[] = {"Stereo", "Left ADC", "Right ADC", + "Channel Swap"}; + +static const struct soc_enum wm8753_enum[] = { +SOC_ENUM_SINGLE(WM8753_BASS, 7, 2, wm8753_base), +SOC_ENUM_SINGLE(WM8753_BASS, 4, 6, wm8753_base_filter), +SOC_ENUM_SINGLE(WM8753_TREBLE, 6, 2, wm8753_treble), +SOC_ENUM_SINGLE(WM8753_ALC1, 7, 4, wm8753_alc_func), +SOC_ENUM_SINGLE(WM8753_NGATE, 1, 2, wm8753_ng_type), +SOC_ENUM_SINGLE(WM8753_3D, 7, 2, wm8753_3d_func), +SOC_ENUM_SINGLE(WM8753_3D, 6, 2, wm8753_3d_uc), +SOC_ENUM_SINGLE(WM8753_3D, 5, 2, wm8753_3d_lc), +SOC_ENUM_SINGLE(WM8753_DAC, 1, 4, wm8753_deemp), +SOC_ENUM_SINGLE(WM8753_DAC, 4, 4, wm8753_mono_mix), +SOC_ENUM_SINGLE(WM8753_DAC, 6, 2, wm8753_dac_phase), +SOC_ENUM_SINGLE(WM8753_INCTL1, 3, 4, wm8753_line_mix), +SOC_ENUM_SINGLE(WM8753_INCTL1, 2, 2, wm8753_mono_mux), +SOC_ENUM_SINGLE(WM8753_INCTL1, 1, 2, wm8753_right_mux), +SOC_ENUM_SINGLE(WM8753_INCTL1, 0, 2, wm8753_left_mux), +SOC_ENUM_SINGLE(WM8753_INCTL2, 6, 4, wm8753_rxmsel), +SOC_ENUM_SINGLE(WM8753_INCTL2, 4, 4, wm8753_sidetone_mux), +SOC_ENUM_SINGLE(WM8753_OUTCTL, 7, 4, wm8753_mono2_src), +SOC_ENUM_SINGLE(WM8753_OUTCTL, 0, 3, wm8753_out3), +SOC_ENUM_SINGLE(WM8753_ADCTL2, 7, 3, wm8753_out4), +SOC_ENUM_SINGLE(WM8753_ADCIN, 2, 3, wm8753_radcsel), +SOC_ENUM_SINGLE(WM8753_ADCIN, 0, 3, wm8753_ladcsel), +SOC_ENUM_SINGLE(WM8753_ADCIN, 4, 4, wm8753_mono_adc), +SOC_ENUM_SINGLE(WM8753_ADC, 2, 4, wm8753_adc_hp), +SOC_ENUM_SINGLE(WM8753_ADC, 4, 2, wm8753_adc_filter), +SOC_ENUM_SINGLE(WM8753_MICBIAS, 6, 3, wm8753_mic_sel), +SOC_ENUM_SINGLE(WM8753_IOCTL, 2, 4, wm8753_dai_mode), +SOC_ENUM_SINGLE(WM8753_ADC, 7, 4, wm8753_dat_sel), +}; + + +static int wm8753_get_dai(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); + + ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; + return 0; +} + +static int wm8753_set_dai(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); + + if (((mode &0xc) >> 2) == ucontrol->value.integer.value[0]) + return 0; + + mode &= 0xfff3; + mode |= (ucontrol->value.integer.value[0] << 2); + + wm8753_write(codec, WM8753_IOCTL, mode); + wm8753_set_dai_mode(codec, ucontrol->value.integer.value[0]); + return 1; +} + +static const struct snd_kcontrol_new wm8753_snd_controls[] = { +SOC_DOUBLE_R("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0), + +SOC_DOUBLE_R("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0), + +SOC_DOUBLE_R("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V, 0, 127, 0), +SOC_DOUBLE_R("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0, 127, 0), + +SOC_SINGLE("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0), + +SOC_DOUBLE_R("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7, 1), +SOC_DOUBLE_R("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4, 7, 1), +SOC_DOUBLE_R("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7, 1), + +SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7, 1, 0), +SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7, 1, 0), + +SOC_SINGLE("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1), +SOC_SINGLE("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1), +SOC_SINGLE("Mono Voice Playback Volume", WM8753_MOUTM2, 4, 7, 1), +SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0), + +SOC_ENUM("Bass Boost", wm8753_enum[0]), +SOC_ENUM("Bass Filter", wm8753_enum[1]), +SOC_SINGLE("Bass Volume", WM8753_BASS, 0, 15, 1), + +SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1), +SOC_ENUM("Treble Cut-off", wm8753_enum[2]), + +SOC_DOUBLE("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1), +SOC_SINGLE("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1), + +SOC_DOUBLE_R("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0), +SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0), +SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1), + +SOC_ENUM("Capture Filter Select", wm8753_enum[23]), +SOC_ENUM("Capture Filter Cut-off", wm8753_enum[24]), +SOC_SINGLE("Capture Filter Switch", WM8753_ADC, 0, 1, 1), + +SOC_SINGLE("ALC Capture Target Volume", WM8753_ALC1, 0, 7, 0), +SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1, 4, 7, 0), +SOC_ENUM("ALC Capture Function", wm8753_enum[3]), +SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2, 8, 1, 0), +SOC_SINGLE("ALC Capture Hold Time", WM8753_ALC2, 0, 15, 1), +SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3, 4, 15, 1), +SOC_SINGLE("ALC Capture Attack Time", WM8753_ALC3, 0, 15, 0), +SOC_SINGLE("ALC Capture NG Threshold", WM8753_NGATE, 3, 31, 0), +SOC_ENUM("ALC Capture NG Type", wm8753_enum[4]), +SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE, 0, 1, 0), + +SOC_ENUM("3D Function", wm8753_enum[5]), +SOC_ENUM("3D Upper Cut-off", wm8753_enum[6]), +SOC_ENUM("3D Lower Cut-off", wm8753_enum[7]), +SOC_SINGLE("3D Volume", WM8753_3D, 1, 15, 0), +SOC_SINGLE("3D Switch", WM8753_3D, 0, 1, 0), + +SOC_SINGLE("Capture 6dB Attenuate", WM8753_ADCTL1, 2, 1, 0), +SOC_SINGLE("Playback 6dB Attenuate", WM8753_ADCTL1, 1, 1, 0), + +SOC_ENUM("De-emphasis", wm8753_enum[8]), +SOC_ENUM("Playback Mono Mix", wm8753_enum[9]), +SOC_ENUM("Playback Phase", wm8753_enum[10]), + +SOC_SINGLE("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0), +SOC_SINGLE("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0), + +SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai), + +SOC_ENUM("ADC Data Select", wm8753_enum[27]), +}; + +/* add non dapm controls */ +static int wm8753_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(wm8753_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&wm8753_snd_controls[i],codec, NULL)); + if (err < 0) + return err; + } + return 0; +} + +/* + * _DAPM_ Controls + */ + +/* Left Mixer */ +static const struct snd_kcontrol_new wm8753_left_mixer_controls[] = { +SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2, 8, 1, 0), +SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2, 7, 1, 0), +SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1, 8, 1, 0), +SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1, 7, 1, 0), +}; + +/* Right mixer */ +static const struct snd_kcontrol_new wm8753_right_mixer_controls[] = { +SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2, 8, 1, 0), +SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2, 7, 1, 0), +SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1, 8, 1, 0), +SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1, 7, 1, 0), +}; + +/* Mono mixer */ +static const struct snd_kcontrol_new wm8753_mono_mixer_controls[] = { +SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1, 8, 1, 0), +SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2, 8, 1, 0), +SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2, 3, 1, 0), +SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2, 7, 1, 0), +SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1, 7, 1, 0), +}; + +/* Mono 2 Mux */ +static const struct snd_kcontrol_new wm8753_mono2_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[17]); + +/* Out 3 Mux */ +static const struct snd_kcontrol_new wm8753_out3_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[18]); + +/* Out 4 Mux */ +static const struct snd_kcontrol_new wm8753_out4_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[19]); + +/* ADC Mono Mix */ +static const struct snd_kcontrol_new wm8753_adc_mono_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[22]); + +/* Record mixer */ +static const struct snd_kcontrol_new wm8753_record_mixer_controls[] = { +SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2, 3, 1, 0), +SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1, 3, 1, 0), +SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1, 7, 1, 0), +}; + +/* Left ADC mux */ +static const struct snd_kcontrol_new wm8753_adc_left_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[21]); + +/* Right ADC mux */ +static const struct snd_kcontrol_new wm8753_adc_right_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[20]); + +/* MIC mux */ +static const struct snd_kcontrol_new wm8753_mic_mux_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[16]); + +/* ALC mixer */ +static const struct snd_kcontrol_new wm8753_alc_mixer_controls[] = { +SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2, 3, 1, 0), +SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2, 2, 1, 0), +SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2, 1, 1, 0), +SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2, 0, 1, 0), +}; + +/* Left Line mux */ +static const struct snd_kcontrol_new wm8753_line_left_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[14]); + +/* Right Line mux */ +static const struct snd_kcontrol_new wm8753_line_right_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[13]); + +/* Mono Line mux */ +static const struct snd_kcontrol_new wm8753_line_mono_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[12]); + +/* Line mux and mixer */ +static const struct snd_kcontrol_new wm8753_line_mux_mix_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[11]); + +/* Rx mux and mixer */ +static const struct snd_kcontrol_new wm8753_rx_mux_mix_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[15]); + +/* Mic Selector Mux */ +static const struct snd_kcontrol_new wm8753_mic_sel_mux_controls = +SOC_DAPM_ENUM("Route", wm8753_enum[25]); + +static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { +SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1, 5, 0), +SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4, 0, 0, + &wm8753_left_mixer_controls[0], ARRAY_SIZE(wm8753_left_mixer_controls)), +SND_SOC_DAPM_PGA("Left Out 1", WM8753_PWR3, 8, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left Out 2", WM8753_PWR3, 6, 0, NULL, 0), +SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", WM8753_PWR1, 3, 0), +SND_SOC_DAPM_OUTPUT("LOUT1"), +SND_SOC_DAPM_OUTPUT("LOUT2"), +SND_SOC_DAPM_MIXER("Right Mixer", WM8753_PWR4, 1, 0, + &wm8753_right_mixer_controls[0], ARRAY_SIZE(wm8753_right_mixer_controls)), +SND_SOC_DAPM_PGA("Right Out 1", WM8753_PWR3, 7, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right Out 2", WM8753_PWR3, 5, 0, NULL, 0), +SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", WM8753_PWR1, 2, 0), +SND_SOC_DAPM_OUTPUT("ROUT1"), +SND_SOC_DAPM_OUTPUT("ROUT2"), +SND_SOC_DAPM_MIXER("Mono Mixer", WM8753_PWR4, 2, 0, + &wm8753_mono_mixer_controls[0], ARRAY_SIZE(wm8753_mono_mixer_controls)), +SND_SOC_DAPM_PGA("Mono Out 1", WM8753_PWR3, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA("Mono Out 2", WM8753_PWR3, 1, 0, NULL, 0), +SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0), +SND_SOC_DAPM_OUTPUT("MONO1"), +SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls), +SND_SOC_DAPM_OUTPUT("MONO2"), +SND_SOC_DAPM_MIXER("Out3 Left + Right", -1, 0, 0, NULL, 0), +SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls), +SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0), +SND_SOC_DAPM_OUTPUT("OUT3"), +SND_SOC_DAPM_MUX("Out4 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out4_controls), +SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3, 3, 0, NULL, 0), +SND_SOC_DAPM_OUTPUT("OUT4"), +SND_SOC_DAPM_MIXER("Playback Mixer", WM8753_PWR4, 3, 0, + &wm8753_record_mixer_controls[0], + ARRAY_SIZE(wm8753_record_mixer_controls)), +SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8753_PWR2, 3, 0), +SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8753_PWR2, 2, 0), +SND_SOC_DAPM_MUX("Capture Left Mixer", SND_SOC_NOPM, 0, 0, + &wm8753_adc_mono_controls), +SND_SOC_DAPM_MUX("Capture Right Mixer", SND_SOC_NOPM, 0, 0, + &wm8753_adc_mono_controls), +SND_SOC_DAPM_MUX("Capture Left Mux", SND_SOC_NOPM, 0, 0, + &wm8753_adc_left_controls), +SND_SOC_DAPM_MUX("Capture Right Mux", SND_SOC_NOPM, 0, 0, + &wm8753_adc_right_controls), +SND_SOC_DAPM_MUX("Mic Sidetone Mux", SND_SOC_NOPM, 0, 0, + &wm8753_mic_mux_controls), +SND_SOC_DAPM_PGA("Left Capture Volume", WM8753_PWR2, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2, 4, 0, NULL, 0), +SND_SOC_DAPM_MIXER("ALC Mixer", WM8753_PWR2, 6, 0, + &wm8753_alc_mixer_controls[0], ARRAY_SIZE(wm8753_alc_mixer_controls)), +SND_SOC_DAPM_MUX("Line Left Mux", SND_SOC_NOPM, 0, 0, + &wm8753_line_left_controls), +SND_SOC_DAPM_MUX("Line Right Mux", SND_SOC_NOPM, 0, 0, + &wm8753_line_right_controls), +SND_SOC_DAPM_MUX("Line Mono Mux", SND_SOC_NOPM, 0, 0, + &wm8753_line_mono_controls), +SND_SOC_DAPM_MUX("Line Mixer", WM8753_PWR2, 0, 0, + &wm8753_line_mux_mix_controls), +SND_SOC_DAPM_MUX("Rx Mixer", WM8753_PWR2, 1, 0, + &wm8753_rx_mux_mix_controls), +SND_SOC_DAPM_PGA("Mic 1 Volume", WM8753_PWR2, 8, 0, NULL, 0), +SND_SOC_DAPM_PGA("Mic 2 Volume", WM8753_PWR2, 7, 0, NULL, 0), +SND_SOC_DAPM_MUX("Mic Selection Mux", SND_SOC_NOPM, 0, 0, + &wm8753_mic_sel_mux_controls), +SND_SOC_DAPM_INPUT("LINE1"), +SND_SOC_DAPM_INPUT("LINE2"), +SND_SOC_DAPM_INPUT("RXP"), +SND_SOC_DAPM_INPUT("RXN"), +SND_SOC_DAPM_INPUT("ACIN"), +SND_SOC_DAPM_OUTPUT("ACOP"), +SND_SOC_DAPM_INPUT("MIC1N"), +SND_SOC_DAPM_INPUT("MIC1"), +SND_SOC_DAPM_INPUT("MIC2N"), +SND_SOC_DAPM_INPUT("MIC2"), +SND_SOC_DAPM_VMID("VREF"), +}; + +static const char *audio_map[][3] = { + /* left mixer */ + {"Left Mixer", "Left Playback Switch", "Left DAC"}, + {"Left Mixer", "Voice Playback Switch", "Voice DAC"}, + {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"}, + {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"}, + + /* right mixer */ + {"Right Mixer", "Right Playback Switch", "Right DAC"}, + {"Right Mixer", "Voice Playback Switch", "Voice DAC"}, + {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"}, + {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"}, + + /* mono mixer */ + {"Mono Mixer", "Voice Playback Switch", "Voice DAC"}, + {"Mono Mixer", "Left Playback Switch", "Left DAC"}, + {"Mono Mixer", "Right Playback Switch", "Right DAC"}, + {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"}, + {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"}, + + /* left out */ + {"Left Out 1", NULL, "Left Mixer"}, + {"Left Out 2", NULL, "Left Mixer"}, + {"LOUT1", NULL, "Left Out 1"}, + {"LOUT2", NULL, "Left Out 2"}, + + /* right out */ + {"Right Out 1", NULL, "Right Mixer"}, + {"Right Out 2", NULL, "Right Mixer"}, + {"ROUT1", NULL, "Right Out 1"}, + {"ROUT2", NULL, "Right Out 2"}, + + /* mono 1 out */ + {"Mono Out 1", NULL, "Mono Mixer"}, + {"MONO1", NULL, "Mono Out 1"}, + + /* mono 2 out */ + {"Mono 2 Mux", "Left + Right", "Out3 Left + Right"}, + {"Mono 2 Mux", "Inverted Mono 1", "MONO1"}, + {"Mono 2 Mux", "Left", "Left Mixer"}, + {"Mono 2 Mux", "Right", "Right Mixer"}, + {"Mono Out 2", NULL, "Mono 2 Mux"}, + {"MONO2", NULL, "Mono Out 2"}, + + /* out 3 */ + {"Out3 Left + Right", NULL, "Left Mixer"}, + {"Out3 Left + Right", NULL, "Right Mixer"}, + {"Out3 Mux", "VREF", "VREF"}, + {"Out3 Mux", "Left + Right", "Out3 Left + Right"}, + {"Out3 Mux", "ROUT2", "ROUT2"}, + {"Out 3", NULL, "Out3 Mux"}, + {"OUT3", NULL, "Out 3"}, + + /* out 4 */ + {"Out4 Mux", "VREF", "VREF"}, + {"Out4 Mux", "Capture ST", "Capture ST Mixer"}, + {"Out4 Mux", "LOUT2", "LOUT2"}, + {"Out 4", NULL, "Out4 Mux"}, + {"OUT4", NULL, "Out 4"}, + + /* record mixer */ + {"Playback Mixer", "Left Capture Switch", "Left Mixer"}, + {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"}, + {"Playback Mixer", "Right Capture Switch", "Right Mixer"}, + + /* Mic/SideTone Mux */ + {"Mic Sidetone Mux", "Left PGA", "Left Capture Volume"}, + {"Mic Sidetone Mux", "Right PGA", "Right Capture Volume"}, + {"Mic Sidetone Mux", "Mic 1", "Mic 1 Volume"}, + {"Mic Sidetone Mux", "Mic 2", "Mic 2 Volume"}, + + /* Capture Left Mux */ + {"Capture Left Mux", "PGA", "Left Capture Volume"}, + {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"}, + {"Capture Left Mux", "Line", "LINE1"}, + + /* Capture Right Mux */ + {"Capture Right Mux", "PGA", "Right Capture Volume"}, + {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"}, + {"Capture Right Mux", "Sidetone", "Capture ST Mixer"}, + + /* Mono Capture mixer-mux */ + {"Capture Right Mixer", "Stereo", "Capture Right Mux"}, + {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"}, + {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"}, + {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"}, + {"Capture Right Mixer", "Analogue Mix Right", "Capture Right Mux"}, + {"Capture Left Mixer", "Digital Mono Mix", "Capture Left Mux"}, + {"Capture Left Mixer", "Digital Mono Mix", "Capture Right Mux"}, + {"Capture Right Mixer", "Digital Mono Mix", "Capture Left Mux"}, + {"Capture Right Mixer", "Digital Mono Mix", "Capture Right Mux"}, + + /* ADC */ + {"Left ADC", NULL, "Capture Left Mixer"}, + {"Right ADC", NULL, "Capture Right Mixer"}, + + /* Left Capture Volume */ + {"Left Capture Volume", NULL, "ACIN"}, + + /* Right Capture Volume */ + {"Right Capture Volume", NULL, "Mic 2 Volume"}, + + /* ALC Mixer */ + {"ALC Mixer", "Line Capture Switch", "Line Mixer"}, + {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"}, + {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"}, + {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"}, + + /* Line Left Mux */ + {"Line Left Mux", "Line 1", "LINE1"}, + {"Line Left Mux", "Rx Mix", "Rx Mixer"}, + + /* Line Right Mux */ + {"Line Right Mux", "Line 2", "LINE2"}, + {"Line Right Mux", "Rx Mix", "Rx Mixer"}, + + /* Line Mono Mux */ + {"Line Mono Mux", "Line Mix", "Line Mixer"}, + {"Line Mono Mux", "Rx Mix", "Rx Mixer"}, + + /* Line Mixer/Mux */ + {"Line Mixer", "Line 1 + 2", "LINE1"}, + {"Line Mixer", "Line 1 - 2", "LINE1"}, + {"Line Mixer", "Line 1 + 2", "LINE2"}, + {"Line Mixer", "Line 1 - 2", "LINE2"}, + {"Line Mixer", "Line 1", "LINE1"}, + {"Line Mixer", "Line 2", "LINE2"}, + + /* Rx Mixer/Mux */ + {"Rx Mixer", "RXP - RXN", "RXP"}, + {"Rx Mixer", "RXP + RXN", "RXP"}, + {"Rx Mixer", "RXP - RXN", "RXN"}, + {"Rx Mixer", "RXP + RXN", "RXN"}, + {"Rx Mixer", "RXP", "RXP"}, + {"Rx Mixer", "RXN", "RXN"}, + + /* Mic 1 Volume */ + {"Mic 1 Volume", NULL, "MIC1N"}, + {"Mic 1 Volume", NULL, "Mic Selection Mux"}, + + /* Mic 2 Volume */ + {"Mic 2 Volume", NULL, "MIC2N"}, + {"Mic 2 Volume", NULL, "MIC2"}, + + /* Mic Selector Mux */ + {"Mic Selection Mux", "Mic 1", "MIC1"}, + {"Mic Selection Mux", "Mic 2", "MIC2N"}, + {"Mic Selection Mux", "Mic 3", "MIC2"}, + + /* ACOP */ + {"ACOP", NULL, "ALC Mixer"}, + + /* terminator */ + {NULL, NULL, NULL}, +}; + +static int wm8753_add_widgets(struct snd_soc_codec *codec) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(wm8753_dapm_widgets); i++) + snd_soc_dapm_new_control(codec, &wm8753_dapm_widgets[i]); + + /* set up the WM8753 audio map */ + for (i = 0; audio_map[i][0] != NULL; i++) { + snd_soc_dapm_connect_input(codec, audio_map[i][0], + audio_map[i][1], audio_map[i][2]); + } + + snd_soc_dapm_new_widgets(codec); + return 0; +} + +/* PLL divisors */ +struct _pll_div { + u32 div2:1; + u32 n:4; + u32 k:24; +}; + +/* The size in bits of the pll divide multiplied by 10 + * to allow rounding later */ +#define FIXED_PLL_SIZE ((1 << 22) * 10) + +static void pll_factors(struct _pll_div *pll_div, unsigned int target, + unsigned int source) +{ + u64 Kpart; + unsigned int K, Ndiv, Nmod; + + Ndiv = target / source; + if (Ndiv < 6) { + source >>= 1; + pll_div->div2 = 1; + Ndiv = target / source; + } else + pll_div->div2 = 0; + + if ((Ndiv < 6) || (Ndiv > 12)) + printk(KERN_WARNING + "WM8753 N value outwith recommended range! N = %d\n",Ndiv); + + pll_div->n = Ndiv; + Nmod = target % source; + Kpart = FIXED_PLL_SIZE * (long long)Nmod; + + do_div(Kpart, source); + + K = Kpart & 0xFFFFFFFF; + + /* Check if we need to round */ + if ((K % 10) >= 5) + K += 5; + + /* Move down to proper range now rounding is done */ + K /= 10; + + pll_div->k = K; +} + +static int wm8753_set_dai_pll(struct snd_soc_codec_dai *codec_dai, + int pll_id, unsigned int freq_in, unsigned int freq_out) +{ + u16 reg, enable; + int offset; + struct snd_soc_codec *codec = codec_dai->codec; + + if (pll_id < WM8753_PLL1 || pll_id > WM8753_PLL2) + return -ENODEV; + + if (pll_id == WM8753_PLL1) { + offset = 0; + enable = 0x10; + reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef; + } else { + offset = 4; + enable = 0x8; + reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7; + } + + if (!freq_in || !freq_out) { + /* disable PLL */ + wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026); + wm8753_write(codec, WM8753_CLOCK, reg); + return 0; + } else { + u16 value = 0; + struct _pll_div pll_div; + + pll_factors(&pll_div, freq_out * 8, freq_in); + + /* set up N and K PLL divisor ratios */ + /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */ + value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18); + wm8753_write(codec, WM8753_PLL1CTL2 + offset, value); + + /* bits 8:0 = PLL_K[17:9] */ + value = (pll_div.k & 0x03fe00) >> 9; + wm8753_write(codec, WM8753_PLL1CTL3 + offset, value); + + /* bits 8:0 = PLL_K[8:0] */ + value = pll_div.k & 0x0001ff; + wm8753_write(codec, WM8753_PLL1CTL4 + offset, value); + + /* set PLL as input and enable */ + wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 | + (pll_div.div2 << 3)); + wm8753_write(codec, WM8753_CLOCK, reg | enable); + } + return 0; +} + +struct _coeff_div { + u32 mclk; + u32 rate; + u8 sr:5; + u8 usb:1; +}; + +/* codec hifi mclk (after PLL) clock divider coefficients */ +static const struct _coeff_div coeff_div[] = { + /* 8k */ + {12288000, 8000, 0x6, 0x0}, + {11289600, 8000, 0x16, 0x0}, + {18432000, 8000, 0x7, 0x0}, + {16934400, 8000, 0x17, 0x0}, + {12000000, 8000, 0x6, 0x1}, + + /* 11.025k */ + {11289600, 11025, 0x18, 0x0}, + {16934400, 11025, 0x19, 0x0}, + {12000000, 11025, 0x19, 0x1}, + + /* 16k */ + {12288000, 16000, 0xa, 0x0}, + {18432000, 16000, 0xb, 0x0}, + {12000000, 16000, 0xa, 0x1}, + + /* 22.05k */ + {11289600, 22050, 0x1a, 0x0}, + {16934400, 22050, 0x1b, 0x0}, + {12000000, 22050, 0x1b, 0x1}, + + /* 32k */ + {12288000, 32000, 0xc, 0x0}, + {18432000, 32000, 0xd, 0x0}, + {12000000, 32000, 0xa, 0x1}, + + /* 44.1k */ + {11289600, 44100, 0x10, 0x0}, + {16934400, 44100, 0x11, 0x0}, + {12000000, 44100, 0x11, 0x1}, + + /* 48k */ + {12288000, 48000, 0x0, 0x0}, + {18432000, 48000, 0x1, 0x0}, + {12000000, 48000, 0x0, 0x1}, + + /* 88.2k */ + {11289600, 88200, 0x1e, 0x0}, + {16934400, 88200, 0x1f, 0x0}, + {12000000, 88200, 0x1f, 0x1}, + + /* 96k */ + {12288000, 96000, 0xe, 0x0}, + {18432000, 96000, 0xf, 0x0}, + {12000000, 96000, 0xe, 0x1}, +}; + +static int get_coeff(int mclk, int rate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) + return i; + } + return -EINVAL; +} + +/* + * Clock after PLL and dividers + */ +static int wm8753_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct wm8753_priv *wm8753 = codec->private_data; + + switch (freq) { + case 11289600: + case 12000000: + case 12288000: + case 16934400: + case 18432000: + if (clk_id == WM8753_MCLK) { + wm8753->sysclk = freq; + return 0; + } else if (clk_id == WM8753_PCMCLK) { + wm8753->pcmclk = freq; + return 0; + } + break; + } + return -EINVAL; +} + +/* + * Set's ADC and Voice DAC format. + */ +static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec; + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + voice |= 0x0002; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + voice |= 0x0001; + break; + case SND_SOC_DAIFMT_DSP_A: + voice |= 0x0003; + break; + case SND_SOC_DAIFMT_DSP_B: + voice |= 0x0013; + break; + default: + return -EINVAL; + } + + wm8753_write(codec, WM8753_PCM, voice); + return 0; +} + +/* + * Set PCM DAI bit size and sample rate. + */ +static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->codec; + struct wm8753_priv *wm8753 = codec->private_data; + u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; + u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; + + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + voice |= 0x0004; + break; + case SNDRV_PCM_FORMAT_S24_LE: + voice |= 0x0008; + break; + case SNDRV_PCM_FORMAT_S32_LE: + voice |= 0x000c; + break; + } + + /* sample rate */ + if (params_rate(params) * 384 == wm8753->pcmclk) + srate |= 0x80; + wm8753_write(codec, WM8753_SRATE1, srate); + + wm8753_write(codec, WM8753_PCM, voice); + return 0; +} + +/* + * Set's PCM dai fmt and BCLK. + */ +static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 voice, ioctl; + + voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f; + ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBM_CFM: + ioctl |= 0x2; + case SND_SOC_DAIFMT_CBM_CFS: + voice |= 0x0040; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* frame inversion not valid for DSP modes */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + voice |= 0x0080; + break; + default: + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + voice &= ~0x0010; + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + voice |= 0x0090; + break; + case SND_SOC_DAIFMT_IB_NF: + voice |= 0x0080; + break; + case SND_SOC_DAIFMT_NB_IF: + voice |= 0x0010; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + wm8753_write(codec, WM8753_PCM, voice); + wm8753_write(codec, WM8753_IOCTL, ioctl); + return 0; +} + +static int wm8753_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai, + int div_id, int div) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 reg; + + switch (div_id) { + case WM8753_PCMDIV: + reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f; + wm8753_write(codec, WM8753_CLOCK, reg | div); + break; + case WM8753_BCLKDIV: + reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7; + wm8753_write(codec, WM8753_SRATE2, reg | div); + break; + case WM8753_VXCLKDIV: + reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f; + wm8753_write(codec, WM8753_SRATE2, reg | div); + break; + default: + return -EINVAL; + } + return 0; +} + +/* + * Set's HiFi DAC format. + */ +static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0; + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + hifi |= 0x0002; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + hifi |= 0x0001; + break; + case SND_SOC_DAIFMT_DSP_A: + hifi |= 0x0003; + break; + case SND_SOC_DAIFMT_DSP_B: + hifi |= 0x0013; + break; + default: + return -EINVAL; + } + + wm8753_write(codec, WM8753_HIFI, hifi); + return 0; +} + +/* + * Set's I2S DAI format. + */ +static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 ioctl, hifi; + + hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f; + ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBM_CFM: + ioctl |= 0x1; + case SND_SOC_DAIFMT_CBM_CFS: + hifi |= 0x0040; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* frame inversion not valid for DSP modes */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + hifi |= 0x0080; + break; + default: + return -EINVAL; + } + break; + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + hifi &= ~0x0010; + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + hifi |= 0x0090; + break; + case SND_SOC_DAIFMT_IB_NF: + hifi |= 0x0080; + break; + case SND_SOC_DAIFMT_NB_IF: + hifi |= 0x0010; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + wm8753_write(codec, WM8753_HIFI, hifi); + wm8753_write(codec, WM8753_IOCTL, ioctl); + return 0; +} + +/* + * Set PCM DAI bit size and sample rate. + */ +static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_codec *codec = socdev->codec; + struct wm8753_priv *wm8753 = codec->private_data; + u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; + u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; + int coeff; + + /* is digital filter coefficient valid ? */ + coeff = get_coeff(wm8753->sysclk, params_rate(params)); + if (coeff < 0) { + printk(KERN_ERR "wm8753 invalid MCLK or rate\n"); + return coeff; + } + wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) | + coeff_div[coeff].usb); + + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + hifi |= 0x0004; + break; + case SNDRV_PCM_FORMAT_S24_LE: + hifi |= 0x0008; + break; + case SNDRV_PCM_FORMAT_S32_LE: + hifi |= 0x000c; + break; + } + + wm8753_write(codec, WM8753_HIFI, hifi); + return 0; +} + +static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 clock; + + /* set clk source as pcmclk */ + clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; + wm8753_write(codec, WM8753_CLOCK, clock); + + if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) + return -EINVAL; + return wm8753_pcm_set_dai_fmt(codec_dai, fmt); +} + +static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) + return -EINVAL; + return wm8753_i2s_set_dai_fmt(codec_dai, fmt); +} + +static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 clock; + + /* set clk source as pcmclk */ + clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; + wm8753_write(codec, WM8753_CLOCK, clock); + + if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) + return -EINVAL; + return wm8753_i2s_set_dai_fmt(codec_dai, fmt); +} + +static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 clock; + + /* set clk source as mclk */ + clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; + wm8753_write(codec, WM8753_CLOCK, clock | 0x4); + + if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) + return -EINVAL; + if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) + return -EINVAL; + return wm8753_i2s_set_dai_fmt(codec_dai, fmt); +} + +static int wm8753_mute(struct snd_soc_codec_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; + + /* the digital mute covers the HiFi and Voice DAC's on the WM8753. + * make sure we check if they are not both active when we mute */ + if (mute && dai->id == 1) { + if (!wm8753_dai[WM8753_DAI_VOICE].playback.active || + !wm8753_dai[WM8753_DAI_HIFI].playback.active) + wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); + } else { + if (mute) + wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); + else + wm8753_write(codec, WM8753_DAC, mute_reg); + } + + return 0; +} + +static int wm8753_dapm_event(struct snd_soc_codec *codec, int event) +{ + u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e; + + switch (event) { + case SNDRV_CTL_POWER_D0: /* full On */ + /* set vmid to 50k and unmute dac */ + wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); + break; + case SNDRV_CTL_POWER_D1: /* partial On */ + case SNDRV_CTL_POWER_D2: /* partial On */ + /* set vmid to 5k for quick power up */ + wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); + break; + case SNDRV_CTL_POWER_D3hot: /* Off, with power */ + /* mute dac and set vmid to 500k, enable VREF */ + wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141); + break; + case SNDRV_CTL_POWER_D3cold: /* Off, without power */ + wm8753_write(codec, WM8753_PWR1, 0x0001); + break; + } + codec->dapm_state = event; + return 0; +} + +#define WM8753_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) + +#define WM8753_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE) + +/* + * The WM8753 supports upto 4 different and mutually exclusive DAI + * configurations. This gives 2 PCM's available for use, hifi and voice. + * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI + * is connected between the wm8753 and a BT codec or GSM modem. + * + * 1. Voice over PCM DAI - HIFI DAC over HIFI DAI + * 2. Voice over HIFI DAI - HIFI disabled + * 3. Voice disabled - HIFI over HIFI + * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture + */ +static const struct snd_soc_codec_dai wm8753_all_dai[] = { +/* DAI HiFi mode 1 */ +{ .name = "WM8753 HiFi", + .id = 1, + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .capture = { /* dummy for fast DAI switching */ + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .ops = { + .hw_params = wm8753_i2s_hw_params,}, + .dai_ops = { + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode1h_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, +}, +/* DAI Voice mode 1 */ +{ .name = "WM8753 Voice", + .id = 1, + .playback = { + .stream_name = "Voice Playback", + .channels_min = 1, + .channels_max = 1, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .ops = { + .hw_params = wm8753_pcm_hw_params,}, + .dai_ops = { + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode1v_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, +}, +/* DAI HiFi mode 2 - dummy */ +{ .name = "WM8753 HiFi", + .id = 2, +}, +/* DAI Voice mode 2 */ +{ .name = "WM8753 Voice", + .id = 2, + .playback = { + .stream_name = "Voice Playback", + .channels_min = 1, + .channels_max = 1, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .ops = { + .hw_params = wm8753_pcm_hw_params,}, + .dai_ops = { + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode2_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, +}, +/* DAI HiFi mode 3 */ +{ .name = "WM8753 HiFi", + .id = 3, + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .ops = { + .hw_params = wm8753_i2s_hw_params,}, + .dai_ops = { + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode3_4_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, +}, +/* DAI Voice mode 3 - dummy */ +{ .name = "WM8753 Voice", + .id = 3, +}, +/* DAI HiFi mode 4 */ +{ .name = "WM8753 HiFi", + .id = 4, + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8753_RATES, + .formats = WM8753_FORMATS,}, + .ops = { + .hw_params = wm8753_i2s_hw_params,}, + .dai_ops = { + .digital_mute = wm8753_mute, + .set_fmt = wm8753_mode3_4_set_dai_fmt, + .set_clkdiv = wm8753_set_dai_clkdiv, + .set_pll = wm8753_set_dai_pll, + .set_sysclk = wm8753_set_dai_sysclk, + }, +}, +/* DAI Voice mode 4 - dummy */ +{ .name = "WM8753 Voice", + .id = 4, +}, +}; + +struct snd_soc_codec_dai wm8753_dai[2]; +EXPORT_SYMBOL_GPL(wm8753_dai); + +static void wm8753_set_dai_mode(struct snd_soc_codec *codec, unsigned int mode) +{ + if (mode < 4) { + int playback_active, capture_active, codec_active, pop_wait; + void *private_data; + + playback_active = wm8753_dai[0].playback.active; + capture_active = wm8753_dai[0].capture.active; + codec_active = wm8753_dai[0].active; + private_data = wm8753_dai[0].private_data; + pop_wait = wm8753_dai[0].pop_wait; + wm8753_dai[0] = wm8753_all_dai[mode << 1]; + wm8753_dai[0].playback.active = playback_active; + wm8753_dai[0].capture.active = capture_active; + wm8753_dai[0].active = codec_active; + wm8753_dai[0].private_data = private_data; + wm8753_dai[0].pop_wait = pop_wait; + + playback_active = wm8753_dai[1].playback.active; + capture_active = wm8753_dai[1].capture.active; + codec_active = wm8753_dai[1].active; + private_data = wm8753_dai[1].private_data; + pop_wait = wm8753_dai[1].pop_wait; + wm8753_dai[1] = wm8753_all_dai[(mode << 1) + 1]; + wm8753_dai[1].playback.active = playback_active; + wm8753_dai[1].capture.active = capture_active; + wm8753_dai[1].active = codec_active; + wm8753_dai[1].private_data = private_data; + wm8753_dai[1].pop_wait = pop_wait; + } + wm8753_dai[0].codec = codec; + wm8753_dai[1].codec = codec; +} + +static void wm8753_work(struct work_struct *work) +{ + struct snd_soc_codec *codec = + container_of(work, struct snd_soc_codec, delayed_work.work); + wm8753_dapm_event(codec, codec->dapm_state); +} + +static int wm8753_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + + /* we only need to suspend if we are a valid card */ + if(!codec->card) + return 0; + + wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + return 0; +} + +static int wm8753_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + int i; + u8 data[2]; + u16 *cache = codec->reg_cache; + + /* we only need to resume if we are a valid card */ + if(!codec->card) + return 0; + + /* Sync reg_cache with the hardware */ + for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { + if (i + 1 == WM8753_RESET) + continue; + data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); + data[1] = cache[i] & 0x00ff; + codec->hw_write(codec->control_data, data, 2); + } + + wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3hot); + + /* charge wm8753 caps */ + if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) { + wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2); + codec->dapm_state = SNDRV_CTL_POWER_D0; + schedule_delayed_work(&codec->delayed_work, + msecs_to_jiffies(caps_charge)); + } + + return 0; +} + +/* + * initialise the WM8753 driver + * register the mixer and dsp interfaces with the kernel + */ +static int wm8753_init(struct snd_soc_device *socdev) +{ + struct snd_soc_codec *codec = socdev->codec; + int reg, ret = 0; + + codec->name = "WM8753"; + codec->owner = THIS_MODULE; + codec->read = wm8753_read_reg_cache; + codec->write = wm8753_write; + codec->dapm_event = wm8753_dapm_event; + codec->dai = wm8753_dai; + codec->num_dai = 2; + codec->reg_cache_size = sizeof(wm8753_reg); + codec->reg_cache = kmemdup(wm8753_reg, sizeof(wm8753_reg), GFP_KERNEL); + + if (codec->reg_cache == NULL) + return -ENOMEM; + + wm8753_set_dai_mode(codec, 0); + + wm8753_reset(codec); + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + printk(KERN_ERR "wm8753: failed to create pcms\n"); + goto pcm_err; + } + + /* charge output caps */ + wm8753_dapm_event(codec, SNDRV_CTL_POWER_D2); + codec->dapm_state = SNDRV_CTL_POWER_D3hot; + schedule_delayed_work(&codec->delayed_work, + msecs_to_jiffies(caps_charge)); + + /* set the update bits */ + reg = wm8753_read_reg_cache(codec, WM8753_LDAC); + wm8753_write(codec, WM8753_LDAC, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_RDAC); + wm8753_write(codec, WM8753_RDAC, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_LADC); + wm8753_write(codec, WM8753_LADC, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_RADC); + wm8753_write(codec, WM8753_RADC, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V); + wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V); + wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V); + wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V); + wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_LINVOL); + wm8753_write(codec, WM8753_LINVOL, reg | 0x0100); + reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); + wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); + + wm8753_add_controls(codec); + wm8753_add_widgets(codec); + ret = snd_soc_register_card(socdev); + if (ret < 0) { + printk(KERN_ERR "wm8753: failed to register card\n"); + goto card_err; + } + return ret; + +card_err: + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +pcm_err: + kfree(codec->reg_cache); + return ret; +} + +/* If the i2c layer weren't so broken, we could pass this kind of data + around */ +static struct snd_soc_device *wm8753_socdev; + +#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) + +/* + * WM8753 2 wire address is determined by GPIO5 + * state during powerup. + * low = 0x1a + * high = 0x1b + */ +static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; + +/* Magic definition of all other variables and things */ +I2C_CLIENT_INSMOD; + +static struct i2c_driver wm8753_i2c_driver; +static struct i2c_client client_template; + +static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind) +{ + struct snd_soc_device *socdev = wm8753_socdev; + struct wm8753_setup_data *setup = socdev->codec_data; + struct snd_soc_codec *codec = socdev->codec; + struct i2c_client *i2c; + int ret; + + if (addr != setup->i2c_address) + return -ENODEV; + + client_template.adapter = adap; + client_template.addr = addr; + + i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL); + if (i2c == NULL){ + kfree(codec); + return -ENOMEM; + } + i2c_set_clientdata(i2c, codec); + codec->control_data = i2c; + + ret = i2c_attach_client(i2c); + if (ret < 0) { + err("failed to attach codec at addr %x\n", addr); + goto err; + } + + ret = wm8753_init(socdev); + if (ret < 0) { + err("failed to initialise WM8753\n"); + goto err; + } + + return ret; + +err: + kfree(codec); + kfree(i2c); + return ret; +} + +static int wm8753_i2c_detach(struct i2c_client *client) +{ + struct snd_soc_codec *codec = i2c_get_clientdata(client); + i2c_detach_client(client); + kfree(codec->reg_cache); + kfree(client); + return 0; +} + +static int wm8753_i2c_attach(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &addr_data, wm8753_codec_probe); +} + +/* corgi i2c codec control layer */ +static struct i2c_driver wm8753_i2c_driver = { + .driver = { + .name = "WM8753 I2C Codec", + .owner = THIS_MODULE, + }, + .id = I2C_DRIVERID_WM8753, + .attach_adapter = wm8753_i2c_attach, + .detach_client = wm8753_i2c_detach, + .command = NULL, +}; + +static struct i2c_client client_template = { + .name = "WM8753", + .driver = &wm8753_i2c_driver, +}; +#endif + +static int wm8753_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct wm8753_setup_data *setup; + struct snd_soc_codec *codec; + struct wm8753_priv *wm8753; + int ret = 0; + + info("WM8753 Audio Codec %s", WM8753_VERSION); + + setup = socdev->codec_data; + codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (codec == NULL) + return -ENOMEM; + + wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); + if (wm8753 == NULL) { + kfree(codec); + return -ENOMEM; + } + + codec->private_data = wm8753; + socdev->codec = codec; + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + wm8753_socdev = socdev; + INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); + +#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) + if (setup->i2c_address) { + normal_i2c[0] = setup->i2c_address; + codec->hw_write = (hw_write_t)i2c_master_send; + ret = i2c_add_driver(&wm8753_i2c_driver); + if (ret != 0) + printk(KERN_ERR "can't add i2c driver"); + } +#else + /* Add other interfaces here */ +#endif + return ret; +} + +/* + * This function forces any delayed work to be queued and run. + */ +static int run_delayed_work(struct delayed_work *dwork) +{ + int ret; + + /* cancel any work waiting to be queued. */ + ret = cancel_delayed_work(dwork); + + /* if there was any work waiting then we run it now and + * wait for it's completion */ + if (ret) { + schedule_delayed_work(dwork, 0); + flush_scheduled_work(); + } + return ret; +} + +/* power down chip */ +static int wm8753_remove(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + + if (codec->control_data) + wm8753_dapm_event(codec, SNDRV_CTL_POWER_D3cold); + run_delayed_work(&codec->delayed_work); + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); +#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) + i2c_del_driver(&wm8753_i2c_driver); +#endif + kfree(codec->private_data); + kfree(codec); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_wm8753 = { + .probe = wm8753_probe, + .remove = wm8753_remove, + .suspend = wm8753_suspend, + .resume = wm8753_resume, +}; + +EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); + +MODULE_DESCRIPTION("ASoC WM8753 driver"); +MODULE_AUTHOR("Liam Girdwood"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h new file mode 100644 index 0000000..95e2a1f --- /dev/null +++ b/sound/soc/codecs/wm8753.h @@ -0,0 +1,126 @@ +/* + * wm8753.h -- audio driver for WM8753 + * + * Copyright 2003 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifndef _WM8753_H +#define _WM8753_H + +/* WM8753 register space */ + +#define WM8753_DAC 0x01 +#define WM8753_ADC 0x02 +#define WM8753_PCM 0x03 +#define WM8753_HIFI 0x04 +#define WM8753_IOCTL 0x05 +#define WM8753_SRATE1 0x06 +#define WM8753_SRATE2 0x07 +#define WM8753_LDAC 0x08 +#define WM8753_RDAC 0x09 +#define WM8753_BASS 0x0a +#define WM8753_TREBLE 0x0b +#define WM8753_ALC1 0x0c +#define WM8753_ALC2 0x0d +#define WM8753_ALC3 0x0e +#define WM8753_NGATE 0x0f +#define WM8753_LADC 0x10 +#define WM8753_RADC 0x11 +#define WM8753_ADCTL1 0x12 +#define WM8753_3D 0x13 +#define WM8753_PWR1 0x14 +#define WM8753_PWR2 0x15 +#define WM8753_PWR3 0x16 +#define WM8753_PWR4 0x17 +#define WM8753_ID 0x18 +#define WM8753_INTPOL 0x19 +#define WM8753_INTEN 0x1a +#define WM8753_GPIO1 0x1b +#define WM8753_GPIO2 0x1c +#define WM8753_RESET 0x1f +#define WM8753_RECMIX1 0x20 +#define WM8753_RECMIX2 0x21 +#define WM8753_LOUTM1 0x22 +#define WM8753_LOUTM2 0x23 +#define WM8753_ROUTM1 0x24 +#define WM8753_ROUTM2 0x25 +#define WM8753_MOUTM1 0x26 +#define WM8753_MOUTM2 0x27 +#define WM8753_LOUT1V 0x28 +#define WM8753_ROUT1V 0x29 +#define WM8753_LOUT2V 0x2a +#define WM8753_ROUT2V 0x2b +#define WM8753_MOUTV 0x2c +#define WM8753_OUTCTL 0x2d +#define WM8753_ADCIN 0x2e +#define WM8753_INCTL1 0x2f +#define WM8753_INCTL2 0x30 +#define WM8753_LINVOL 0x31 +#define WM8753_RINVOL 0x32 +#define WM8753_MICBIAS 0x33 +#define WM8753_CLOCK 0x34 +#define WM8753_PLL1CTL1 0x35 +#define WM8753_PLL1CTL2 0x36 +#define WM8753_PLL1CTL3 0x37 +#define WM8753_PLL1CTL4 0x38 +#define WM8753_PLL2CTL1 0x39 +#define WM8753_PLL2CTL2 0x3a +#define WM8753_PLL2CTL3 0x3b +#define WM8753_PLL2CTL4 0x3c +#define WM8753_BIASCTL 0x3d +#define WM8753_ADCTL2 0x3f + +struct wm8753_setup_data { + unsigned short i2c_address; +}; + +#define WM8753_PLL1 0 +#define WM8753_PLL2 1 + +/* clock inputs */ +#define WM8753_MCLK 0 +#define WM8753_PCMCLK 1 + +/* clock divider id's */ +#define WM8753_PCMDIV 0 +#define WM8753_BCLKDIV 1 +#define WM8753_VXCLKDIV 2 + +/* PCM clock dividers */ +#define WM8753_PCM_DIV_1 (0 << 6) +#define WM8753_PCM_DIV_3 (2 << 6) +#define WM8753_PCM_DIV_5_5 (3 << 6) +#define WM8753_PCM_DIV_2 (4 << 6) +#define WM8753_PCM_DIV_4 (5 << 6) +#define WM8753_PCM_DIV_6 (6 << 6) +#define WM8753_PCM_DIV_8 (7 << 6) + +/* BCLK clock dividers */ +#define WM8753_BCLK_DIV_1 (0 << 3) +#define WM8753_BCLK_DIV_2 (1 << 3) +#define WM8753_BCLK_DIV_4 (2 << 3) +#define WM8753_BCLK_DIV_8 (3 << 3) +#define WM8753_BCLK_DIV_16 (4 << 3) + +/* VXCLK clock dividers */ +#define WM8753_VXCLK_DIV_1 (0 << 6) +#define WM8753_VXCLK_DIV_2 (1 << 6) +#define WM8753_VXCLK_DIV_4 (2 << 6) +#define WM8753_VXCLK_DIV_8 (3 << 6) +#define WM8753_VXCLK_DIV_16 (4 << 6) + +#define WM8753_DAI_HIFI 0 +#define WM8753_DAI_VOICE 1 + +extern struct snd_soc_codec_dai wm8753_dai[2]; +extern struct snd_soc_codec_device soc_codec_dev_wm8753; + +#endif -- cgit v0.10.2 From 33703b73980f0a84251c298d00ad5fbcce81ca31 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 16 Apr 2007 19:18:15 +0200 Subject: [ALSA] ASoC WM8753 codec - build changes This patch adds the WM8753 codec driver to the kernel build system. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index ec2a278..e5fb437 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -10,6 +10,10 @@ config SND_SOC_WM8750 tristate depends on SND_SOC +config SND_SOC_WM8753 + tristate + depends on SND_SOC + config SND_SOC_WM9712 tristate depends on SND_SOC diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3249a6e..e39a747 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -1,9 +1,11 @@ snd-soc-ac97-objs := ac97.o snd-soc-wm8731-objs := wm8731.o snd-soc-wm8750-objs := wm8750.o +snd-soc-wm8753-objs := wm8753.o snd-soc-wm9712-objs := wm9712.o obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o +obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o -- cgit v0.10.2 From 5d0cedee53938832acc4a5081658f0ce31680c0f Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Mon, 16 Apr 2007 19:20:17 +0200 Subject: [ALSA] ASoC export AC97 DAI This patch exports the ASoC AC97 Digital Audio Interface as a GPL'ed symbol. Signed-off-by: Graeme Gregory Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index 55bc55e..0cdef97 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -60,6 +60,7 @@ static struct snd_soc_codec_dai ac97_dai = { .ops = { .prepare = ac97_prepare,}, }; +EXPORT_SYMBOL_GPL(ac97_dai); static unsigned int ac97_read(struct snd_soc_codec *codec, unsigned int reg) diff --git a/sound/soc/codecs/ac97.h b/sound/soc/codecs/ac97.h index 930ddfc..2bf6d69 100644 --- a/sound/soc/codecs/ac97.h +++ b/sound/soc/codecs/ac97.h @@ -14,5 +14,6 @@ #define __LINUX_SND_SOC_AC97_H extern struct snd_soc_codec_device soc_codec_dev_ac97; +extern struct snd_soc_codec_dai ac97_dai; #endif -- cgit v0.10.2 From c45e20eb214648014d2df54ddb9f8665b231629f Mon Sep 17 00:00:00 2001 From: Abhijit Bhopatkar Date: Tue, 17 Apr 2007 11:57:16 +0200 Subject: [ALSA] hda-codec - Add first generation macbook subsystem ID First generation MacBooks were getting ignored by sigmatel drivers and wrongly being identified as MACMINI. This patch makes them identify as MACBOOK. Signed-off-by: Abhijit Bhopatkar Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 612d355..5e6d02c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1911,6 +1911,9 @@ static int patch_stac922x(struct hda_codec *codec) */ printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); switch (codec->subsystem_id) { + case 0x106b0a00: /* MacBook First generatoin */ + spec->board_config = STAC_MACBOOK; + break; case 0x106b0200: /* MacBook Pro first generation */ spec->board_config = STAC_MACBOOK_PRO_V1; break; -- cgit v0.10.2 From 7f1bc26e7df85957bcc48442f135e7a6f85e5edc Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Tue, 17 Apr 2007 12:35:18 +0200 Subject: [ALSA] ASoC Samsung S3c24xx updates - audio DMA cleanup This patch cleans up the audio DMA for the Samsung S3C24xx platform. Signed-off-by: Graeme Gregory Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c index f1c0b9f..21dc697 100644 --- a/sound/soc/s3c24xx/s3c24xx-pcm.c +++ b/sound/soc/s3c24xx/s3c24xx-pcm.c @@ -89,7 +89,7 @@ static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream) DBG("Entered %s\n", __FUNCTION__); - while ( prtd->dma_loaded < prtd->dma_limit) { + while (prtd->dma_loaded < prtd->dma_limit) { unsigned long len = prtd->dma_period; DBG("dma_loaded: %d\n",prtd->dma_loaded); @@ -100,7 +100,8 @@ static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream) __FUNCTION__, len); } - ret = s3c2410_dma_enqueue(prtd->params->channel, substream, pos, len); + ret = s3c2410_dma_enqueue(prtd->params->channel, + substream, pos, len); if (ret == 0) { prtd->dma_loaded++; @@ -115,17 +116,19 @@ static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream) } static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, - void *dev_id, int size, - enum s3c2410_dma_buffresult result) + void *dev_id, int size, + enum s3c2410_dma_buffresult result) { struct snd_pcm_substream *substream = dev_id; - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + struct s3c24xx_runtime_data *prtd; DBG("Entered %s\n", __FUNCTION__); if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) return; + prtd = substream->runtime->private_data; + if (substream) snd_pcm_period_elapsed(substream); @@ -173,18 +176,22 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, * sync to pclk, half-word transfers to the IIS-FIFO. */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { s3c2410_dma_devconfig(prtd->params->channel, - S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC | - S3C2410_DISRCC_APB, prtd->params->dma_addr); + S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC | + S3C2410_DISRCC_APB, prtd->params->dma_addr); s3c2410_dma_config(prtd->params->channel, - 2, S3C2410_DCON_SYNC_PCLK | S3C2410_DCON_HANDSHAKE); + prtd->params->dma_size, + S3C2410_DCON_SYNC_PCLK | + S3C2410_DCON_HANDSHAKE); } else { s3c2410_dma_config(prtd->params->channel, - 2, S3C2410_DCON_HANDSHAKE | S3C2410_DCON_SYNC_PCLK); + prtd->params->dma_size, + S3C2410_DCON_HANDSHAKE | + S3C2410_DCON_SYNC_PCLK); s3c2410_dma_devconfig(prtd->params->channel, - S3C2410_DMASRC_HW, 0x3, - prtd->params->dma_addr); + S3C2410_DMASRC_HW, 0x3, + prtd->params->dma_addr); } s3c2410_dma_set_buffdone_fn(prtd->params->channel, @@ -215,7 +222,7 @@ static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream) /* TODO - do we need to ensure DMA flushed */ snd_pcm_set_runtime_buffer(substream, NULL); - if(prtd->params) { + if (prtd->params) { s3c2410_dma_free(prtd->params->channel, prtd->params->client); prtd->params = NULL; } @@ -281,7 +288,8 @@ static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) return ret; } -static snd_pcm_uframes_t s3c24xx_pcm_pointer(struct snd_pcm_substream *substream) +static snd_pcm_uframes_t + s3c24xx_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct s3c24xx_runtime_data *prtd = runtime->private_data; @@ -321,8 +329,6 @@ static int s3c24xx_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct s3c24xx_runtime_data *prtd; - int ret; - DBG("Entered %s\n", __FUNCTION__); snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware); @@ -342,7 +348,7 @@ static int s3c24xx_pcm_close(struct snd_pcm_substream *substream) DBG("Entered %s\n", __FUNCTION__); - if(prtd) + if (prtd) kfree(prtd); else DBG("s3c24xx_pcm_close called with prtd == NULL\n"); @@ -419,8 +425,8 @@ static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm) static u64 s3c24xx_pcm_dmamask = DMA_32BIT_MASK; -static int s3c24xx_pcm_new(struct snd_card *card, struct snd_soc_codec_dai *dai, - struct snd_pcm *pcm) +static int s3c24xx_pcm_new(struct snd_card *card, + struct snd_soc_codec_dai *dai, struct snd_pcm *pcm) { int ret = 0; diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.h b/sound/soc/s3c24xx/s3c24xx-pcm.h index 5dced4a..0088c79 100644 --- a/sound/soc/s3c24xx/s3c24xx-pcm.h +++ b/sound/soc/s3c24xx/s3c24xx-pcm.h @@ -16,15 +16,14 @@ #define ST_OPENED (1<<1) struct s3c24xx_pcm_dma_params { - struct s3c2410_dma_client *client; /* stream identifier */ - int channel; /* Channel ID */ + struct s3c2410_dma_client *client; /* stream identifier */ + int channel; /* Channel ID */ dma_addr_t dma_addr; + int dma_size; /* Size of the DMA transfer */ }; #define S3C24XX_DAI_I2S 0 -extern struct snd_soc_cpu_dai s3c24xx_i2s_dai; - /* platform data */ extern struct snd_soc_platform s3c24xx_soc_platform; extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; -- cgit v0.10.2 From e81208fe5881b700cfb25db1ecb769ecbfff40cc Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Tue, 17 Apr 2007 12:35:48 +0200 Subject: [ALSA] ASoC Samsung S3C24xx updates - i2s This patch adds DMA size fields to the S3C24xx audio DMA params and exports the S3C24xx I2S digital audio interface. Signed-off-by: Graeme Gregory Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index df655a5..8ca314d 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -61,13 +61,15 @@ static struct s3c2410_dma_client s3c24xx_dma_client_in = { static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_out = { .client = &s3c24xx_dma_client_out, .channel = DMACH_I2S_OUT, - .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO + .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, + .dma_size = 2, }; static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_in = { .client = &s3c24xx_dma_client_in, .channel = DMACH_I2S_IN, - .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO + .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, + .dma_size = 2, }; struct s3c24xx_i2s_info { diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/s3c24xx/s3c24xx-i2s.h index f9ca04e..537b4ec 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.h +++ b/sound/soc/s3c24xx/s3c24xx-i2s.h @@ -32,4 +32,6 @@ u32 s3c24xx_i2s_get_clockrate(void); +extern struct snd_soc_cpu_dai s3c24xx_i2s_dai; + #endif /*S3C24XXI2S_H_*/ -- cgit v0.10.2 From 43a23389003f92cc26a84a680008330e094db38d Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 17 Apr 2007 15:41:52 +0200 Subject: [ALSA] ASoC Kconfig description This patch makes the ASoC Kconfig descriptions a little more meaningful. Signed-off-by: Liam Girdwood Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 23a5c3b..10cffc0 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -2,23 +2,25 @@ # SoC audio configuration # -menu "SoC audio support" +menu "System on Chip audio support" depends on SND!=n config SND_SOC_AC97_BUS bool config SND_SOC - tristate "SoC audio support" + tristate "ALSA for SoC audio support" depends on SND select SND_PCM ---help--- - If you want SoC support, you should say Y here and also to the - specific driver for your SoC below. You will also need to select the - specific codec(s) attached to the SoC + If you want ASoC support, you should say Y here and also to the + specific driver for your SoC platform below. + + ASoC provides power efficient ALSA support for embedded battery powered + SoC based systems like PDA's, Phones and Personal Media Players. - This SoC audio support can also be built as a module. If so, the module + This ASoC audio support can also be built as a module. If so, the module will be called snd-soc-core. # All the supported Soc's -- cgit v0.10.2 From fb956c16d92c6c8c8d30e938cce5c17cf737b646 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 18 Apr 2007 23:03:56 +0200 Subject: [ALSA] hda-codec - Fix surround output on AD1986A Fix surround output on AD1986A codec 3stack model. The following bugs are fixed: - init verbs for 3stack disabled the shared surround outputs - a channel mode change resulted in the mute of surrounds Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index fa194f2..2654097 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -751,42 +751,35 @@ static struct hda_verb ad1986a_init_verbs[] = { { } /* end */ }; -/* additional verbs for 3-stack model */ -static struct hda_verb ad1986a_3st_init_verbs[] = { - /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */ - {0x0f, AC_VERB_SET_CONNECT_SEL, 0x4}, - /* Line-in selectors */ - {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, - { } /* end */ -}; - static struct hda_verb ad1986a_ch2_init[] = { /* Surround out -> Line In */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, + /* Line-in selectors */ + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 }, /* CLFE -> Mic in */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */ + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, { } /* end */ }; static struct hda_verb ad1986a_ch4_init[] = { /* Surround out -> Surround */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* CLFE -> Mic in */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, { } /* end */ }; static struct hda_verb ad1986a_ch6_init[] = { /* Surround out -> Surround out */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* CLFE -> CLFE */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 }, { } /* end */ }; @@ -895,9 +888,8 @@ static int patch_ad1986a(struct hda_codec *codec) case AD1986A_3STACK: spec->num_mixers = 2; spec->mixers[1] = ad1986a_3st_mixers; - spec->num_init_verbs = 3; - spec->init_verbs[1] = ad1986a_3st_init_verbs; - spec->init_verbs[2] = ad1986a_ch2_init; + spec->num_init_verbs = 2; + spec->init_verbs[1] = ad1986a_ch2_init; spec->channel_mode = ad1986a_modes; spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); spec->need_dac_fix = 1; -- cgit v0.10.2 From 57b14f24d2a7aca65ddc6432fa89ebedf1219cc7 Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Wed, 18 Apr 2007 23:05:36 +0200 Subject: [ALSA] hda-codec - Add support for Gigabyte S-Series GA-M57SLI-S4 motherboard Added the support for Gigabyte S-Series GA-M57SLI-S4 motherboard (model=6stack-dig). Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f5944e0..61dffb8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5978,6 +5978,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), -- cgit v0.10.2 From c9758b2182bdcccce31e1be474bfcd75b69cff0c Mon Sep 17 00:00:00 2001 From: Milind Arun Choudhary Date: Thu, 19 Apr 2007 15:22:56 +0200 Subject: [ALSA] sound: SPIN_LOCK_UNLOCKED cleanup SPIN_LOCK_UNLOCKED cleanup,use __SPIN_LOCK_UNLOCKED instead Signed-off-by: Milind Arun Choudhary Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c index db1635a..3d4e32c 100644 --- a/sound/soc/at91/at91-ssc.c +++ b/sound/soc/at91/at91-ssc.c @@ -152,20 +152,20 @@ static struct at91_ssc_info { } ssc_info[NUM_SSC_DEVICES] = { { .name = "ssc0", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock), .dir_mask = 0, .initialized = 0, }, #if NUM_SSC_DEVICES == 3 { .name = "ssc1", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock), .dir_mask = 0, .initialized = 0, }, { .name = "ssc2", - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock), .dir_mask = 0, .initialized = 0, }, -- cgit v0.10.2 From 2078f38c8008f5c54d9523ae19af32b9a0c5530e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 20 Apr 2007 12:30:28 +0200 Subject: [ALSA] intel8x0 - Fix Oops in crash kernel When intel8x0 driver is loaded in the crash kernel, it gets Oops occasionally. This is because the irq handler gets called before the proper hardware initialization. Now defer it after snd_intel8x0_chip_init(). (reference: http://lkml.org/lkml/2007/3/5/252) Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 7cf2dcb..202f720 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -2493,6 +2493,7 @@ static int intel8x0_resume(struct pci_dev *pci) return -EIO; } pci_set_master(pci); + snd_intel8x0_chip_init(chip, 0); if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_SHARED, card->shortname, chip)) { printk(KERN_ERR "intel8x0: unable to grab IRQ %d, " @@ -2502,7 +2503,6 @@ static int intel8x0_resume(struct pci_dev *pci) } chip->irq = pci->irq; synchronize_irq(chip->irq); - snd_intel8x0_chip_init(chip, 0); /* re-initialize mixer stuff */ if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) { @@ -2862,16 +2862,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA; chip->int_sta_mask = int_sta_masks; - /* request irq after initializaing int_sta_mask, etc */ - if (request_irq(pci->irq, snd_intel8x0_interrupt, - IRQF_SHARED, card->shortname, chip)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); - snd_intel8x0_free(chip); - return -EBUSY; - } - chip->irq = pci->irq; pci_set_master(pci); - synchronize_irq(chip->irq); switch(chip->device_type) { case DEVICE_INTEL_ICH4: @@ -2901,6 +2892,15 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, return err; } + /* request irq after initializaing int_sta_mask, etc */ + if (request_irq(pci->irq, snd_intel8x0_interrupt, + IRQF_SHARED, card->shortname, chip)) { + snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); + snd_intel8x0_free(chip); + return -EBUSY; + } + chip->irq = pci->irq; + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { snd_intel8x0_free(chip); return err; -- cgit v0.10.2 From 9422db4018cbfaa1a330b018a2bf6527d282b417 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 20 Apr 2007 16:11:43 +0200 Subject: [ALSA] hda-codec - Fix 8-channel auto-configuration Fix the auto-configuration of 8-channel devices. The sequence numbers of usual 7.1 outputs are: 0/1/2/4 = Front/CLFE/Rear/Side Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 2fdd165..a58fdf4 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2242,18 +2242,13 @@ int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, * HDA sequence is: * 4-ch: front/surr => OK as it is * 6-ch: front/clfe/surr - * 8-ch: front/clfe/side/surr + * 8-ch: front/clfe/rear/side|fc */ switch (cfg->line_outs) { case 3: - nid = cfg->line_out_pins[1]; - cfg->line_out_pins[1] = cfg->line_out_pins[2]; - cfg->line_out_pins[2] = nid; - break; case 4: nid = cfg->line_out_pins[1]; - cfg->line_out_pins[1] = cfg->line_out_pins[3]; - cfg->line_out_pins[3] = cfg->line_out_pins[2]; + cfg->line_out_pins[1] = cfg->line_out_pins[2]; cfg->line_out_pins[2] = nid; break; } -- cgit v0.10.2 From 479ef4369f65abf4c3e7bbe44ef934a465257ee1 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 23 Apr 2007 11:54:41 +0200 Subject: [ALSA] sound: fix incorrect use of platform_device_register() The platform_device allocated by platform_device_alloc() should be added to the device hierarchy by platform_device_add() instead of platform_device_register(). Otherwise it will hit WARN_ON() in platform_device_register(). by illegal refcount. This patch fixes such incorrect usages in portman2x4 and mts64 drivers. Also it removes unnecessary trailing whitespaces. Signed-off-by: Akinobu Mita Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index 6c9f4c9..ebb1bda 100644 --- a/sound/drivers/mts64.c +++ b/sound/drivers/mts64.c @@ -892,13 +892,13 @@ static void __devinit snd_mts64_attach(struct parport *p) struct platform_device *device; device = platform_device_alloc(PLATFORM_DRIVER, device_count); - if (!device) + if (!device) return; /* Temporary assignment to forward the parport */ platform_set_drvdata(device, p); - if (platform_device_register(device) < 0) { + if (platform_device_add(device) < 0) { platform_device_put(device); return; } diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c index b2d0ba4..497cafb 100644 --- a/sound/drivers/portman2x4.c +++ b/sound/drivers/portman2x4.c @@ -676,13 +676,13 @@ static void __devinit snd_portman_attach(struct parport *p) struct platform_device *device; device = platform_device_alloc(PLATFORM_DRIVER, device_count); - if (!device) + if (!device) return; /* Temporary assignment to forward the parport */ platform_set_drvdata(device, p); - if (platform_device_register(device) < 0) { + if (platform_device_add(device) < 0) { platform_device_put(device); return; } -- cgit v0.10.2 From 658fba0efe93fdef44f65cff391ae2a881e30d90 Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Mon, 23 Apr 2007 16:41:12 +0200 Subject: [ALSA] hda-codec - Add support for Asus A8JN Laptop This patch adds support for the Asus A8JN Laptop. Other modes were tested, this one worked best. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2654097..f6f3c2c 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -834,6 +834,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD), + SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK), SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK), SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP), SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK), -- cgit v0.10.2 From d258e24a39a75834f25c39f90a3a429978e9b896 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 23 Apr 2007 17:16:21 +0200 Subject: [ALSA] hda-codec - Add line_out_type to auto_pin_cfg struct Added line_out_type field to auto_pin_cfg struct to provide the pin type of default line_outs. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index a58fdf4..9c8ac15 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2288,12 +2288,14 @@ int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, sizeof(cfg->speaker_pins)); cfg->speaker_outs = 0; memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); + cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; } else if (cfg->hp_outs) { cfg->line_outs = cfg->hp_outs; memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins)); cfg->hp_outs = 0; memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); + cfg->line_out_type = AUTO_PIN_HP_OUT; } } diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 3505a67..be12b88 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -222,6 +222,12 @@ enum { AUTO_PIN_LAST }; +enum { + AUTO_PIN_LINE_OUT, + AUTO_PIN_SPEAKER_OUT, + AUTO_PIN_HP_OUT +}; + extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; struct auto_pin_cfg { @@ -230,6 +236,7 @@ struct auto_pin_cfg { int speaker_outs; hda_nid_t speaker_pins[5]; int hp_outs; + int line_out_type; /* AUTO_PIN_XXX_OUT */ hda_nid_t hp_pins[5]; hda_nid_t input_pins[AUTO_PIN_LAST]; hda_nid_t dig_out_pin; -- cgit v0.10.2 From baba8ee9d12d17cac1042a5c816aef7d6610a6c3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 23 Apr 2007 17:17:48 +0200 Subject: [ALSA] hda-codec - Fix output pin types in auto configuration Use PIN_HP output type for HP pin widgets accordingly, instead of always applying PIN_OUT. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 61dffb8..6cace82 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3095,6 +3095,14 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, } } +static int get_pin_type(int line_out_type) +{ + if (line_out_type == AUTO_PIN_HP_OUT) + return PIN_HP; + else + return PIN_OUT; +} + static void alc880_auto_init_multi_out(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -3103,7 +3111,8 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec) alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; - alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); + int pin_type = get_pin_type(spec->autocfg.line_out_type); + alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); } } @@ -4292,8 +4301,10 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) alc_subsystem_id(codec, 0x10, 0x15, 0x0f); nid = spec->autocfg.line_out_pins[0]; - if (nid) - alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); + if (nid) { + int pin_type = get_pin_type(spec->autocfg.line_out_type); + alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); + } nid = spec->autocfg.speaker_pins[0]; if (nid) @@ -4301,7 +4312,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) nid = spec->autocfg.hp_pins[0]; if (nid) - alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); + alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); } #define ALC260_PIN_CD_NID 0x16 @@ -5164,8 +5175,9 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec) alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) - alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, + alc882_auto_set_output_and_unmute(codec, nid, pin_type, i); } } @@ -6185,8 +6197,9 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) - alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, + alc883_auto_set_output_and_unmute(codec, nid, pin_type, i); } } @@ -8182,8 +8195,9 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec) alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) - alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, + alc861_auto_set_output_and_unmute(codec, nid, pin_type, spec->multiout.dac_nids[i]); } } @@ -8892,9 +8906,10 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec) alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) alc861vd_auto_set_output_and_unmute(codec, nid, - PIN_OUT, i); + pin_type, i); } } @@ -9867,8 +9882,9 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec) for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) - alc662_auto_set_output_and_unmute(codec, nid, PIN_OUT, + alc662_auto_set_output_and_unmute(codec, nid, pin_type, i); } } -- cgit v0.10.2 From bccad14e9a931027b72f20fe7caba68fea760e7b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 24 Apr 2007 12:23:53 +0200 Subject: [ALSA] hda-intel - Fix detection of audio codec on Toshiba A100 Some boards have the audio codec on slot #3 while the modem codec on slot #0. The driver should continue to probe the slots when no audio codec is found. This fixes the problem of no device on Toshiba A100 (and some other ATI SB450 devices). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 5e478b9..d409515 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -979,7 +979,7 @@ static unsigned int azx_max_codecs[] __devinitdata = { static int __devinit azx_codec_create(struct azx *chip, const char *model) { struct hda_bus_template bus_temp; - int c, codecs, err; + int c, codecs, audio_codecs, err; memset(&bus_temp, 0, sizeof(bus_temp)); bus_temp.private_data = chip; @@ -991,16 +991,19 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) return err; - codecs = 0; + codecs = audio_codecs = 0; for (c = 0; c < AZX_MAX_CODECS; c++) { if ((chip->codec_mask & (1 << c)) & probe_mask) { - err = snd_hda_codec_new(chip->bus, c, NULL); + struct hda_codec *codec; + err = snd_hda_codec_new(chip->bus, c, &codec); if (err < 0) continue; codecs++; + if (codec->afg) + audio_codecs++; } } - if (!codecs) { + if (!audio_codecs) { /* probe additional slots if no codec is found */ for (; c < azx_max_codecs[chip->driver_type]; c++) { if ((chip->codec_mask & (1 << c)) & probe_mask) { -- cgit v0.10.2 From c5a30f85fd56c06efddbe6f4885c7968245c2d8a Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Tue, 24 Apr 2007 12:27:36 +0200 Subject: [ALSA] ice1724 - Misc fixes for Prodigy192 - always set 256fs in SPDIF master clock mode - disable deemphasis filter in AK4114 for Prodigy192 Signed-off-by: Pavel Hofman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 6a29bcf..ee620de 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -1666,7 +1666,12 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, spin_lock_irq(&ice->reg_lock); oval = inb(ICEMT1724(ice, RATE)); if (ucontrol->value.enumerated.item[0] == spdif) { + unsigned char i2s_oval; outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE)); + /* setting 256fs */ + i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT)); + outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, + ICEMT1724(ice, I2S_FORMAT)); } else { rate = rates[ucontrol->value.integer.value[0] % 15]; if (rate <= get_max_rate(ice)) { diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index ae08a07..f03c02c 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -26,6 +26,13 @@ * CCLK (pin 34) -- GPIO9 pin 76 * CSN (pin 35) -- GPIO8 pin 75 * - output data Mode 7 (24bit, I2S, slave) + * - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which + * outputs master clock to SPMCLKIN of ice1724. + * Experimentally I found out that only a combination of + * OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 - + * VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct + * sampling rate. That means the the FPGA doubles the + * MCK01 rate. * * Copyright (c) 2003 Takashi Iwai * Copyright (c) 2003 Dimitromanolakis Apostolos @@ -714,7 +721,10 @@ static int prodigy192_ak4114_init(struct snd_ice1712 *ice) { static const unsigned char ak4114_init_vals[] = { AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, - AK4114_DIF_I24I2S, /* ice1724 expects I2S and provides clock */ + /* ice1724 expects I2S and provides clock, + * DEM0 disables the deemphasis filter + */ + AK4114_DIF_I24I2S | AK4114_DEM0 , AK4114_TX1E, AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */ 0, -- cgit v0.10.2 From b7589ceba035d3f5f1baf69cc67991abd2ce6688 Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Tue, 24 Apr 2007 17:56:55 +0200 Subject: [ALSA] HDA-Intel: Fix headphone squeal on Conexant audio This patch fixes the headphone squeal and noise on Conexant CX20551 (Waikiki) audio. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 2349b5e..ddaa811 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -993,22 +993,10 @@ static struct snd_kcontrol_new cxt5047_mixers[] = { HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT), HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = cxt5047_hp_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = cxt_eapd_info, - .get = cxt_eapd_get, - .put = cxt5047_hp_master_sw_put, - .private_value = 0x13, - }, + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x00, HDA_OUTPUT), + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x13, 0x00, HDA_OUTPUT), {} }; @@ -1079,7 +1067,8 @@ static struct hda_verb cxt5047_init_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, /* HP, Speaker */ - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, + {0x13, AC_VERB_SET_CONNECT_SEL,0x1}, {0x1d, AC_VERB_SET_CONNECT_SEL,0x0}, /* Record selector: Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, -- cgit v0.10.2 From f223a9fc3d5707c354588570e2cf1f3abf6b1f84 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 25 Apr 2007 13:38:31 +0200 Subject: [ALSA] hda-codec - Fix model for ASUS A9rp Fixed the model (asus-laptop) for ASUS A9rp with ALC660 codec. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6cace82..d9213fa 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8308,6 +8308,7 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), + SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), -- cgit v0.10.2 From b7dd2b349a9fa9e4347780c2bbb41e51484b5bb5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 26 Apr 2007 14:13:44 +0200 Subject: [ALSA] Don't use request_firmware if internal firmwares are defined Don't use request_firmware() if the internal firmwares are defined via Kconfig. Otherwise it results in a significant delay at loading time (minutes). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index ef71e50..92e2bc4 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c @@ -161,13 +161,17 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep) */ static void snd_sb_csp_free(struct snd_hwdep *hwdep) { +#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL int i; +#endif struct snd_sb_csp *p = hwdep->private_data; if (p) { if (p->running & SNDRV_SB_CSP_ST_RUNNING) snd_sb_csp_stop(p); +#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL for (i = 0; i < ARRAY_SIZE(p->csp_programs); ++i) release_firmware(p->csp_programs[i]); +#endif kfree(p); } } @@ -712,22 +716,19 @@ static int snd_sb_csp_firmware_load(struct snd_sb_csp *p, int index, int flags) "sb16/ima_adpcm_capture.csp", }; const struct firmware *program; - int err; BUILD_BUG_ON(ARRAY_SIZE(names) != CSP_PROGRAM_COUNT); program = p->csp_programs[index]; if (!program) { - err = request_firmware(&program, names[index], - p->chip->card->dev); - if (err >= 0) - p->csp_programs[index] = program; - else { #ifdef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL - program = &snd_sb_csp_static_programs[index]; + program = &snd_sb_csp_static_programs[index]; #else + int err = request_firmware(&program, names[index], + p->chip->card->dev); + if (err < 0) return err; #endif - } + p->csp_programs[index] = program; } return snd_sb_csp_load(p, program->data, program->size, flags); } diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c index 3a8c056..0e948a9 100644 --- a/sound/isa/wavefront/wavefront_fx.c +++ b/sound/isa/wavefront/wavefront_fx.c @@ -256,21 +256,21 @@ snd_wavefront_fx_start (snd_wavefront_t *dev) { unsigned int i; int err; - const struct firmware *firmware; + const struct firmware *firmware = NULL; if (dev->fx_initialized) return 0; +#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL + firmware = &yss225_registers_firmware; +#else err = request_firmware(&firmware, "yamaha/yss225_registers.bin", dev->card->dev); if (err < 0) { -#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL - firmware = &yss225_registers_firmware; -#else err = -1; goto out; -#endif } +#endif for (i = 0; i + 1 < firmware->size; i += 2) { if (firmware->data[i] >= 8 && firmware->data[i] < 16) { @@ -293,9 +293,8 @@ snd_wavefront_fx_start (snd_wavefront_t *dev) err = 0; out: -#ifdef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL - if (firmware != &yss225_registers_firmware) +#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL + release_firmware(firmware); #endif - release_firmware(firmware); return err; } diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index e2e59ca..bd7c816 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -2340,26 +2340,25 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy + offsetof(struct KorgSharedBuffer, AdatTimeCode); +#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL + dsp_code = &static_dsp_code; +#else err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); if (err < 0) { release_firmware(dsp_code); -#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL - dsp_code = &static_dsp_code; -#else snd_printk(KERN_ERR "firmware not available\n"); snd_korg1212_free(korg1212); return err; -#endif } +#endif if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), dsp_code->size, &korg1212->dma_dsp) < 0) { snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size); snd_korg1212_free(korg1212); -#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL - if (dsp_code != &static_dsp_code) +#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL + release_firmware(dsp_code); #endif - release_firmware(dsp_code); return -ENOMEM; } @@ -2369,10 +2368,9 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size); -#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL - if (dsp_code != &static_dsp_code) +#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL + release_firmware(dsp_code); #endif - release_firmware(dsp_code); rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0); diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 9badbb3..4c1af42 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -2240,7 +2240,7 @@ static const struct firmware assp_minisrc = { .size = sizeof assp_minisrc_image }; -#endif /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ +#else /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ #ifdef __LITTLE_ENDIAN static inline void snd_m3_convert_from_le(const struct firmware *fw) { } @@ -2255,6 +2255,8 @@ static void snd_m3_convert_from_le(const struct firmware *fw) } #endif +#endif /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ + /* * initialize ASSP @@ -2548,14 +2550,10 @@ static int snd_m3_free(struct snd_m3 *chip) if (chip->iobase) pci_release_regions(chip->pci); -#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL - if (chip->assp_kernel_image != &assp_kernel) +#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL + release_firmware(chip->assp_kernel_image); + release_firmware(chip->assp_minisrc_image); #endif - release_firmware(chip->assp_kernel_image); -#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL - if (chip->assp_minisrc_image != &assp_minisrc) -#endif - release_firmware(chip->assp_minisrc_image); pci_disable_device(chip->pci); kfree(chip); @@ -2745,29 +2743,29 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, return -ENOMEM; } +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL + chip->assp_kernel_image = &assp_kernel; +#else err = request_firmware(&chip->assp_kernel_image, "ess/maestro3_assp_kernel.fw", &pci->dev); if (err < 0) { -#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL - chip->assp_kernel_image = &assp_kernel; -#else snd_m3_free(chip); return err; -#endif } else snd_m3_convert_from_le(chip->assp_kernel_image); +#endif +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL + chip->assp_minisrc_image = &assp_minisrc; +#else err = request_firmware(&chip->assp_minisrc_image, "ess/maestro3_assp_minisrc.fw", &pci->dev); if (err < 0) { -#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL - chip->assp_minisrc_image = &assp_minisrc; -#else snd_m3_free(chip); return err; -#endif } else snd_m3_convert_from_le(chip->assp_minisrc_image); +#endif if ((err = pci_request_regions(pci, card->driver)) < 0) { snd_m3_free(chip); diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index b34c3bc..3d4beca 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -2016,6 +2016,24 @@ static struct firmware snd_ymfpci_controller_1e_microcode = { }; #endif +#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL +static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) +{ + chip->dsp_microcode = &snd_ymfpci_dsp_microcode; + if (chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || + chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || + chip->device_id == PCI_DEVICE_ID_YAMAHA_744 || + chip->device_id == PCI_DEVICE_ID_YAMAHA_754) + chip->controller_microcode = + &snd_ymfpci_controller_1e_microcode; + else + chip->controller_microcode = + &snd_ymfpci_controller_microcode; + return 0; +} + +#else /* use fw_loader */ + #ifdef __LITTLE_ENDIAN static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { } #else @@ -2044,13 +2062,8 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) err = -EINVAL; } } - if (err < 0) { -#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL - chip->dsp_microcode = &snd_ymfpci_dsp_microcode; -#else + if (err < 0) return err; -#endif - } is_1e = chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || chip->device_id == PCI_DEVICE_ID_YAMAHA_744 || @@ -2067,17 +2080,11 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) err = -EINVAL; } } - if (err < 0) { -#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL - chip->controller_microcode = - is_1e ? &snd_ymfpci_controller_1e_microcode - : &snd_ymfpci_controller_microcode; -#else + if (err < 0) return err; -#endif - } return 0; } +#endif static void snd_ymfpci_download_image(struct snd_ymfpci *chip) { @@ -2257,15 +2264,10 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip) pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl); pci_disable_device(chip->pci); -#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL - if (chip->dsp_microcode != &snd_ymfpci_dsp_microcode) -#endif - release_firmware(chip->dsp_microcode); -#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL - if (chip->controller_microcode != &snd_ymfpci_controller_microcode && - chip->controller_microcode != &snd_ymfpci_controller_1e_microcode) +#ifndef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL + release_firmware(chip->dsp_microcode); + release_firmware(chip->controller_microcode); #endif - release_firmware(chip->controller_microcode); kfree(chip); return 0; } -- cgit v0.10.2 From 43ea1d478fe5eaf4441263cf6ddad7dd05e1a399 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 26 Apr 2007 19:12:08 +0200 Subject: [ALSA] hda-codec - Prefer audio codec name as the mixer name Prefer the name of audio codecs as the mixer name even if modem codecs are probed before the audio codecs. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 9c8ac15..ff12de4 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -576,7 +576,8 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, } codec->preset = find_codec_preset(codec); - if (!*bus->card->mixername) + /* audio codec should override the mixer name */ + if (codec->afg || !*bus->card->mixername) snd_hda_get_codec_name(codec, bus->card->mixername, sizeof(bus->card->mixername)); -- cgit v0.10.2 From e6db1119318abdc445d541b560744bd6551b1b3d Mon Sep 17 00:00:00 2001 From: Wolke Liu Date: Fri, 27 Apr 2007 12:20:57 +0200 Subject: [ALSA] hda-intel - Add ATI RS780,R600 HDMI audio support This patch is for ATI RS780 and R600 HDMI support. Signed-off-by: Wolke Liu Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d409515..2fa281c 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -88,6 +88,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{ATI, SB600}," "{ATI, RS600}," "{ATI, RS690}," + "{ATI, RS780}," + "{ATI, R600}," "{VIA, VT8251}," "{VIA, VT8237A}," "{SiS, SIS966}," @@ -1773,6 +1775,8 @@ static struct pci_device_id azx_ids[] = { { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */ { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */ + { 0x1002, 0x960c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS780 HDMI */ + { 0x1002, 0xaa00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI R600 HDMI */ { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c index b89db1b..f8eb4c9 100644 --- a/sound/pci/hda/patch_atihdmi.c +++ b/sound/pci/hda/patch_atihdmi.c @@ -172,6 +172,7 @@ static int patch_atihdmi(struct hda_codec *codec) */ struct hda_codec_preset snd_hda_preset_atihdmi[] = { { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, - { .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi }, + { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, + { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi }, {} /* terminator */ }; -- cgit v0.10.2 From f16928fb53111bc23516372df7f6fed86bdfa661 Mon Sep 17 00:00:00 2001 From: Sylvain FORET Date: Fri, 27 Apr 2007 14:22:36 +0200 Subject: [ALSA] snd_hda_intel: fix for intel imac Add handling of Intel-iMac-specific pinconfig of the sound card. Intel-iMac now handled as a separated subsystem. Signed-off-by: Sylvain FORET Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 5e6d02c..ab6d422 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -62,6 +62,7 @@ enum { STAC_MACBOOK, STAC_MACBOOK_PRO_V1, STAC_MACBOOK_PRO_V2, + STAC_IMAC_INTEL, STAC_922X_MODELS }; @@ -536,6 +537,12 @@ static unsigned int macbook_pro_v2_pin_configs[10] = { 0x400000fc, 0x400000fb, }; +static unsigned int imac_intel_pin_configs[10] = { + 0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe, + 0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa, + 0x400000fc, 0x400000fb, +}; + static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_D945_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, @@ -544,6 +551,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_MACBOOK] = macbook_pro_v1_pin_configs, [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, + [STAC_IMAC_INTEL] = imac_intel_pin_configs, }; static const char *stac922x_models[STAC_922X_MODELS] = { @@ -554,6 +562,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = { [STAC_MACBOOK] = "macbook", [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", [STAC_MACBOOK_PRO_V2] = "macbook-pro", + [STAC_IMAC_INTEL] = "imac-intel", }; static struct snd_pci_quirk stac922x_cfg_tbl[] = { @@ -1920,6 +1929,9 @@ static int patch_stac922x(struct hda_codec *codec) case 0x106b1e00: /* MacBook Pro second generation */ spec->board_config = STAC_MACBOOK_PRO_V2; break; + case 0x106b0700: /* Intel-based iMac */ + spec->board_config = STAC_IMAC_INTEL; + break; } } -- cgit v0.10.2 From 86f55319011499662ec7f78db1640b1d158fcba0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 27 Apr 2007 14:23:55 +0200 Subject: [ALSA] Add description of imac-intel model Added the description of missing imac-intel model for hda-intel driver. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 62f9e4c..d18e12b 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -909,6 +909,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. macbook Intel Mac Book macbook-pro-v1 Intel Mac Book Pro 1st generation macbook-pro Intel Mac Book Pro 2nd generation + imac-intel Intel iMac STAC9202/9250/9251 ref Reference board, base config -- cgit v0.10.2 From 82c8c74107c31673478031e90e24a2b74ca680f2 Mon Sep 17 00:00:00 2001 From: James Courtier-Dutton Date: Thu, 19 Apr 2007 11:14:41 +0100 Subject: [ALSA] snd-emu10k1: Prevent E-Mu 1010 Notebook card from hanging PC. E-Mu 1010 is not currently supported yet. Needs development work. Signed-off-by: James Courtier-Dutton Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 80aa585..a130472 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1216,6 +1216,15 @@ static struct snd_emu_chip_details emu_chip_details[] = { .spi_dac = 1, .i2c_adc = 1, .spk71 = 1} , + {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102, + .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", + .id = "EMU1010", + .emu10k2_chip = 1, + .ca0108_chip = 1, + .ca_cardbus_chip = 1, + .spi_dac = 1, + .i2c_adc = 1, + .spk71 = 1} , {.vendor = 0x1102, .device = 0x0008, .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", .id = "Audigy2", -- cgit v0.10.2 From 27fe0f4b985d8427d93ff6c9457e198ab8ffe035 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 2 May 2007 12:07:55 +0200 Subject: [ALSA] sound/pcmcia/vx/vxpocket.c: fix an if() condition It seems noone ever tried to use this driver with more than one device. Signed-off-by: Adrian Bunk Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 363bcb5..c57e127 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -297,7 +297,7 @@ static int vxpocket_probe(struct pcmcia_device *p_dev) /* find an empty slot from the card list */ for (i = 0; i < SNDRV_CARDS; i++) { - if (! card_alloc & (1 << i)) + if (!(card_alloc & (1 << i))) break; } if (i >= SNDRV_CARDS) { -- cgit v0.10.2 From 6b9fa70a73e8627c2823ee95e7c55d77e0716f1c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 2 May 2007 12:09:48 +0200 Subject: [ALSA] usb-audio - Fix the minimum period size per transfer mode The minimal period size is 125us for high-speed mode while 1ms for full-speed mode. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index b6d8863..78efcff 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -1879,7 +1879,9 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre /* set the period time minimum 1ms */ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, - 1000 * MIN_PACKS_URB, + snd_usb_get_speed(subs->dev) == USB_SPEED_FULL ? + + 1000 * MIN_PACKS_URB : 125 * MIN_PACKS_URB, /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX); if (check_hw_params_convention(subs)) { -- cgit v0.10.2 From 4d69d756d19a4f457749f3667ad7fc8984bba15c Mon Sep 17 00:00:00 2001 From: Tobin Davis Date: Thu, 3 May 2007 12:17:11 +0200 Subject: [ALSA] hda-codec - Add support for new HP DV series laptops This patch adds support for 3 new HP laptops to the Conexant 'Venice' driver. Signed-off-by: Tobin Davis Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index ddaa811..a5a4b2bd 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -787,6 +787,9 @@ static const char *cxt5045_models[CXT5045_MODELS] = { static struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP), SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU), SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP), {} -- cgit v0.10.2 From 81c4899f7ef3675fdc574de2671ff9fa45996cc5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 3 May 2007 12:26:14 +0200 Subject: [ALSA] usbaudio - Revert the minimal period size fix patch The last patch didn't really work (false report). Although the hardware supports 125us minimum period, the current usb-audio driver code assumes the 1ms period in many places. Rollback the change. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 78efcff..8ebc1ad 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -1878,10 +1878,11 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre } /* set the period time minimum 1ms */ + /* FIXME: high-speed mode allows 125us minimum period, but many parts + * in the current code assume the 1ms period. + */ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, - snd_usb_get_speed(subs->dev) == USB_SPEED_FULL ? - - 1000 * MIN_PACKS_URB : 125 * MIN_PACKS_URB, + 1000 * MIN_PACKS_URB, /*(nrpacks * MAX_URBS) * 1000*/ UINT_MAX); if (check_hw_params_convention(subs)) { -- cgit v0.10.2 From 5d403b1923fa352b2cbaf8d0945f7ff872049dae Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 3 May 2007 12:32:29 +0200 Subject: [ALSA] hda-codec - Fix resume of STAC92xx codecs Added a missing call to resume mixer controls for STAC92xx codecs. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index ab6d422..ebf7dde 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1766,6 +1766,7 @@ static int stac92xx_resume(struct hda_codec *codec) stac92xx_init(codec); stac92xx_set_config_regs(codec); + snd_hda_resume_ctls(codec, spec->mixer); for (i = 0; i < spec->num_mixers; i++) snd_hda_resume_ctls(codec, spec->mixers[i]); if (spec->multiout.dig_out_nid) -- cgit v0.10.2 From 1327e2b859d725f94687f80e7719a367501b3be2 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 3 May 2007 17:56:59 +0200 Subject: [ALSA] do not depend on FW_LOADER when internal firmware images are used Since request_firmware() is no longer used when the internal firmware images are used, it is no longer necessary to depend on FW_LOADER in this case. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 376c6b0..cf3803c 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -358,7 +358,7 @@ config SND_SBAWE config SND_SB16_CSP bool "Sound Blaster 16/AWE CSP support" depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC) - select FW_LOADER + select FW_LOADER if !SND_SB16_CSP_FIRMWARE_IN_KERNEL help Say Y here to include support for the CSP core. This special coprocessor can do variable tasks like various compression and @@ -400,7 +400,7 @@ config SND_SSCAPE config SND_WAVEFRONT tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)" depends on SND - select FW_LOADER + select FW_LOADER if !SND_WAVEFRONT_FIRMWARE_IN_KERNEL select SND_OPL3_LIB select SND_MPU401_UART select SND_CS4231_LIB diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 9ed4f2f..61e35ec 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -576,7 +576,7 @@ config SND_INTEL8X0M config SND_KORG1212 tristate "Korg 1212 IO" depends on SND - select FW_LOADER + select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL select SND_PCM help Say Y here to include support for Korg 1212IO soundcards. @@ -596,7 +596,7 @@ config SND_KORG1212_FIRMWARE_IN_KERNEL config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" depends on SND - select FW_LOADER + select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL select SND_AC97_CODEC help Say Y here to include support for soundcards based on ESS Maestro 3 @@ -755,7 +755,7 @@ config SND_VX222 config SND_YMFPCI tristate "Yamaha YMF724/740/744/754" depends on SND - select FW_LOADER + select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC -- cgit v0.10.2 From 7e0af29d6f3964bec3d72c6caeb87a603e660fdf Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 3 May 2007 17:59:54 +0200 Subject: [ALSA] add MODULE_FIRMWARE entries Add MODULE_FIRMWARE() entries, where appropriate. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c index e1920af..9a8154c 100644 --- a/sound/drivers/vx/vx_hwdep.c +++ b/sound/drivers/vx/vx_hwdep.c @@ -30,6 +30,20 @@ #ifdef SND_VX_FW_LOADER +MODULE_FIRMWARE("vx/bx_1_vxp.b56"); +MODULE_FIRMWARE("vx/bx_1_vp4.b56"); +MODULE_FIRMWARE("vx/x1_1_vx2.xlx"); +MODULE_FIRMWARE("vx/x1_2_v22.xlx"); +MODULE_FIRMWARE("vx/x1_1_vxp.xlx"); +MODULE_FIRMWARE("vx/x1_1_vp4.xlx"); +MODULE_FIRMWARE("vx/bd56002.boot"); +MODULE_FIRMWARE("vx/bd563v2.boot"); +MODULE_FIRMWARE("vx/bd563s3.boot"); +MODULE_FIRMWARE("vx/l_1_vx2.d56"); +MODULE_FIRMWARE("vx/l_1_v22.d56"); +MODULE_FIRMWARE("vx/l_1_vxp.d56"); +MODULE_FIRMWARE("vx/l_1_vp4.d56"); + int snd_vx_setup_firmware(struct vx_core *chip) { static char *fw_files[VX_TYPE_NUMS][4] = { diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index 92e2bc4..b279f23 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c @@ -36,6 +36,13 @@ MODULE_AUTHOR("Uros Bizjak "); MODULE_DESCRIPTION("ALSA driver for SB16 Creative Signal Processor"); MODULE_LICENSE("GPL"); +#ifndef CONFIG_SND_SB16_CSP_FIRMWARE_IN_KERNEL +MODULE_FIRMWARE("sb16/mulaw_main.csp"); +MODULE_FIRMWARE("sb16/alaw_main.csp"); +MODULE_FIRMWARE("sb16/ima_adpcm_init.csp"); +MODULE_FIRMWARE("sb16/ima_adpcm_playback.csp"); +MODULE_FIRMWARE("sb16/ima_adpcm_capture.csp"); +#endif #ifdef SNDRV_LITTLE_ENDIAN #define CSP_HDR_VALUE(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c index 0e948a9..fc95a87 100644 --- a/sound/isa/wavefront/wavefront_fx.c +++ b/sound/isa/wavefront/wavefront_fx.c @@ -298,3 +298,7 @@ out: #endif return err; } + +#ifndef CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL +MODULE_FIRMWARE("yamaha/yss225_registers.bin"); +#endif diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c index 8e7fe03..87078d3 100644 --- a/sound/pci/echoaudio/darla20.c +++ b/sound/pci/echoaudio/darla20.c @@ -56,6 +56,8 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/darla20_dsp.fw"); + #define FW_DARLA20_DSP 0 static const struct firmware card_fw[] = { diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c index a13c623..42b48f9 100644 --- a/sound/pci/echoaudio/darla24.c +++ b/sound/pci/echoaudio/darla24.c @@ -60,6 +60,8 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/darla24_dsp.fw"); + #define FW_DARLA24_DSP 0 static const struct firmware card_fw[] = { diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c index 8fb1582..8dbb7ac 100644 --- a/sound/pci/echoaudio/echo3g.c +++ b/sound/pci/echoaudio/echo3g.c @@ -68,6 +68,10 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/echo3g_dsp.fw"); +MODULE_FIRMWARE("ea/3g_asic.fw"); + #define FW_361_LOADER 0 #define FW_ECHO3G_DSP 1 #define FW_3G_ASIC 2 diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c index af4d320..fee2d48 100644 --- a/sound/pci/echoaudio/gina20.c +++ b/sound/pci/echoaudio/gina20.c @@ -60,6 +60,8 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/gina20_dsp.fw"); + #define FW_GINA20_DSP 0 static const struct firmware card_fw[] = { diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c index 9ff454a..d5eae47 100644 --- a/sound/pci/echoaudio/gina24.c +++ b/sound/pci/echoaudio/gina24.c @@ -66,6 +66,12 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/gina24_301_dsp.fw"); +MODULE_FIRMWARE("ea/gina24_361_dsp.fw"); +MODULE_FIRMWARE("ea/gina24_301_asic.fw"); +MODULE_FIRMWARE("ea/gina24_361_asic.fw"); + #define FW_361_LOADER 0 #define FW_GINA24_301_DSP 1 #define FW_GINA24_361_DSP 2 diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c index 37eb726..40f601c 100644 --- a/sound/pci/echoaudio/indigo.c +++ b/sound/pci/echoaudio/indigo.c @@ -58,6 +58,9 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/indigo_dsp.fw"); + #define FW_361_LOADER 0 #define FW_INDIGO_DSP 1 diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c index dc8b918..771c538 100644 --- a/sound/pci/echoaudio/indigodj.c +++ b/sound/pci/echoaudio/indigodj.c @@ -58,6 +58,9 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/indigo_dj_dsp.fw"); + #define FW_361_LOADER 0 #define FW_INDIGO_DJ_DSP 1 diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c index eadf326..49c550d 100644 --- a/sound/pci/echoaudio/indigoio.c +++ b/sound/pci/echoaudio/indigoio.c @@ -59,6 +59,9 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/indigo_io_dsp.fw"); + #define FW_361_LOADER 0 #define FW_INDIGO_IO_DSP 1 diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c index 6cede49..8f5483a 100644 --- a/sound/pci/echoaudio/layla20.c +++ b/sound/pci/echoaudio/layla20.c @@ -66,6 +66,9 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/layla20_dsp.fw"); +MODULE_FIRMWARE("ea/layla20_asic.fw"); + #define FW_LAYLA20_DSP 0 #define FW_LAYLA20_ASIC 1 diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c index 44f7354..0524667 100644 --- a/sound/pci/echoaudio/layla24.c +++ b/sound/pci/echoaudio/layla24.c @@ -68,6 +68,12 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/layla24_dsp.fw"); +MODULE_FIRMWARE("ea/layla24_1_asic.fw"); +MODULE_FIRMWARE("ea/layla24_2A_asic.fw"); +MODULE_FIRMWARE("ea/layla24_2S_asic.fw"); + #define FW_361_LOADER 0 #define FW_LAYLA24_DSP 1 #define FW_LAYLA24_1_ASIC 2 diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c index dc172d0..893c7c2 100644 --- a/sound/pci/echoaudio/mia.c +++ b/sound/pci/echoaudio/mia.c @@ -66,6 +66,9 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/mia_dsp.fw"); + #define FW_361_LOADER 0 #define FW_MIA_DSP 1 diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c index c856ed5..3a5d5b0 100644 --- a/sound/pci/echoaudio/mona.c +++ b/sound/pci/echoaudio/mona.c @@ -64,6 +64,15 @@ #include #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/mona_301_dsp.fw"); +MODULE_FIRMWARE("ea/mona_361_dsp.fw"); +MODULE_FIRMWARE("ea/mona_301_1_asic_48.fw"); +MODULE_FIRMWARE("ea/mona_301_1_asic_96.fw"); +MODULE_FIRMWARE("ea/mona_361_1_asic_48.fw"); +MODULE_FIRMWARE("ea/mona_361_1_asic_96.fw"); +MODULE_FIRMWARE("ea/mona_2_asic.fw"); + #define FW_361_LOADER 0 #define FW_MONA_301_DSP 1 #define FW_MONA_361_DSP 2 diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index a130472..dbc805c 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -49,6 +49,13 @@ #include "p17v.h" +#define HANA_FILENAME "emu/hana.fw" +#define DOCK_FILENAME "emu/audio_dock.fw" + +MODULE_FIRMWARE(HANA_FILENAME); +MODULE_FIRMWARE(DOCK_FILENAME); + + /************************************************************************* * EMU10K1 init / done *************************************************************************/ @@ -693,8 +700,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) int tmp,tmp2; int reg; int err; - const char *hana_filename = "emu/hana.fw"; - const char *dock_filename = "emu/audio_dock.fw"; snd_printk(KERN_INFO "emu1010: Special config.\n"); /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, @@ -735,8 +740,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) return -ENODEV; } snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); - if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename); + if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { + snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); return err; } @@ -938,7 +943,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) /* Return to Audio Dock programming mode */ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); - if ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) { + if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { return err; } snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index bd7c816..5338243 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -416,6 +416,9 @@ struct snd_korg1212 { MODULE_DESCRIPTION("korg1212"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}"); +#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL +MODULE_FIRMWARE("korg/k1212.dsp"); +#endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 4c1af42..8a5ff1c 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -59,6 +59,10 @@ MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI}," "{ESS,Allegro PCI}," "{ESS,Allegro-1 PCI}," "{ESS,Canyon3D-2/LE PCI}}"); +#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL +MODULE_FIRMWARE("ess/maestro3_assp_kernel.fw"); +MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw"); +#endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index ca05075..1d9232d 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c @@ -565,6 +565,9 @@ int snd_mixart_setup_firmware(struct mixart_mgr *mgr) return 0; } +MODULE_FIRMWARE("mixart/miXart8.xlx"); +MODULE_FIRMWARE("mixart/miXart8.elf"); +MODULE_FIRMWARE("mixart/miXart8AES.xlx"); #else /* old style firmware loading */ diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c index 369c19f..d55d8bc 100644 --- a/sound/pci/pcxhr/pcxhr_hwdep.c +++ b/sound/pci/pcxhr/pcxhr_hwdep.c @@ -356,6 +356,12 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) return 0; } +MODULE_FIRMWARE("pcxhr/xi_1_882.dat"); +MODULE_FIRMWARE("pcxhr/xc_1_882.dat"); +MODULE_FIRMWARE("pcxhr/e321_512.e56"); +MODULE_FIRMWARE("pcxhr/b321_512.b56"); +MODULE_FIRMWARE("pcxhr/d321_512.d56"); + #else /* old style firmware loading */ /* pcxhr hwdep interface id string */ diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 952625d..8e54104 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -117,6 +117,7 @@ MODULE_AUTHOR("Peter Gruber "); MODULE_DESCRIPTION("riptide"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}"); +MODULE_FIRMWARE("riptide.hex"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 4b20f84..3b3ef65 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -60,6 +60,12 @@ MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," "{RME HDSP-9652}," "{RME HDSP-9632}}"); +#ifdef HDSP_FW_LOADER +MODULE_FIRMWARE("multiface_firmware.bin"); +MODULE_FIRMWARE("multiface_firmware_rev11.bin"); +MODULE_FIRMWARE("digiface_firmware.bin"); +MODULE_FIRMWARE("digiface_firmware_rev11.bin"); +#endif #define HDSP_MAX_CHANNELS 26 #define HDSP_MAX_DS_CHANNELS 14 diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 3d4beca..ea861bc 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -2084,6 +2084,11 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) return err; return 0; } + +MODULE_FIRMWARE("yamaha/ds1_dsp.fw"); +MODULE_FIRMWARE("yamaha/ds1_ctrl.fw"); +MODULE_FIRMWARE("yamaha/ds1e_ctrl.fw"); + #endif static void snd_ymfpci_download_image(struct snd_ymfpci *chip) -- cgit v0.10.2 From 7b043899992e5d9c0b1a620cdad9158d2e5484d7 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Thu, 3 May 2007 20:50:03 +0200 Subject: [ALSA] hda-codec - bug fixes for stac92xx HDA codecs. * fixed surround playback on stac922x. Pin direction control bits were not being set correctly in stac92xx_set_pinctl(). Specifically it would refuse to set the port as an output if the port was already configured as an input. Last hunk (#8). * fixed an input mux bug on 92xx codecs. When there is more than one possible input calculated for the muxes, the actual mux widget never gets set from its reset default, which is index 0, in the stac9221 case that is port E. So alsamixer/amixer/gnome-mixer report the Mic as being the selected input source, but in fact is something else (line-in port E in stac9221 case). Another problem with this is that if you actually try to set the mux input to 'Mic', nothing happens because *cur_val == idx (see snd_hda_input_mux_put). You have to actually toggle input source to line-in then back to mic to actually set the mux widget. Hunk #7. * fixed some typos in patch_sigmatel.c. Hunk #6. * fix to stac92xx_add_dyn_out_pins() that fixes surround playback on codecs with less that 4 DACs (stac9205 for example). It reads the widget caps cache created by hda_codec to count the total number of analog DACs found. It then uses that to determine whether there will be enough independent DACs available for line/mic switch controls. Hunk #1, #2, and #3. * improvements to stac92xx_auto_fill_dac_nids() to make it more general. This fixes surround playback on some codecs in combination with the fix to stac92xx_add_dyn_out_pins() above. It reads the full connection list now, instead of just the first entry, and then locates an analog DAC in the list. If one is found and it's free, assign it to that line-out. If no free DAC is found for the line-out, return -ENODEV. It also makes sure to actually select the chosen DAC if more than one DAC is input to the pin. Hunks #4, #5. Signed-off-by: Steve Longerbeam Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index ebf7dde..93ae9c2 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1070,11 +1070,23 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) { struct sigmatel_spec *spec = codec->spec; + unsigned int wcaps, wtype; + int i, num_dacs = 0; + + /* use the wcaps cache to count all DACs available for line-outs */ + for (i = 0; i < codec->num_nodes; i++) { + wcaps = codec->wcaps[i]; + wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) + num_dacs++; + } + snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); + switch (cfg->line_outs) { case 3: /* add line-in as side */ - if (cfg->input_pins[AUTO_PIN_LINE]) { + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; @@ -1082,12 +1094,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf break; case 2: /* add line-in as clfe and mic as side */ - if (cfg->input_pins[AUTO_PIN_LINE]) { + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; } - if (cfg->input_pins[AUTO_PIN_MIC]) { + if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1; cfg->line_outs++; @@ -1095,12 +1107,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf break; case 1: /* add line-in as surr and mic as clfe */ - if (cfg->input_pins[AUTO_PIN_LINE]) { + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) { cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; } - if (cfg->input_pins[AUTO_PIN_MIC]) { + if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) { cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1; cfg->line_outs++; @@ -1111,33 +1123,76 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf return 0; } + +static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) +{ + int i; + + for (i = 0; i < spec->multiout.num_dacs; i++) { + if (spec->multiout.dac_nids[i] == nid) + return 1; + } + + return 0; +} + /* - * XXX The line_out pin widget connection list may not be set to the - * desired DAC nid. This is the case on 927x where ports A and B can - * be routed to several DACs. - * - * This requires an analysis of the line-out/hp pin configuration - * to provide a best fit for pin/DAC configurations that are routable. - * For now, 927x DAC4 is not supported and 927x DAC1 output to ports - * A and B is not supported. + * Fill in the dac_nids table from the parsed pin configuration + * This function only works when every pin in line_out_pins[] + * contains atleast one DAC in its connection list. Some 92xx + * codecs are not connected directly to a DAC, such as the 9200 + * and 9202/925x. For those, dac_nids[] must be hard-coded. */ -/* fill in the dac_nids table from the parsed pin configuration */ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { struct sigmatel_spec *spec = codec->spec; - hda_nid_t nid; - int i; - - /* check the pins hardwired to audio widget */ + int i, j, conn_len = 0; + hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; + unsigned int wcaps, wtype; + for (i = 0; i < cfg->line_outs; i++) { nid = cfg->line_out_pins[i]; - spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_CONNECT_LIST, 0) & 0xff; - } + conn_len = snd_hda_get_connections(codec, nid, conn, + HDA_MAX_CONNECTIONS); + for (j = 0; j < conn_len; j++) { + wcaps = snd_hda_param_read(codec, conn[j], + AC_PAR_AUDIO_WIDGET_CAP); + wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + + if (wtype != AC_WID_AUD_OUT || + (wcaps & AC_WCAP_DIGITAL)) + continue; + /* conn[j] is a DAC routed to this line-out */ + if (!is_in_dac_nids(spec, conn[j])) + break; + } + + if (j == conn_len) { + /* error out, no available DAC found */ + snd_printk(KERN_ERR + "%s: No available DAC for pin 0x%x\n", + __func__, nid); + return -ENODEV; + } + + spec->multiout.dac_nids[i] = conn[j]; + spec->multiout.num_dacs++; + if (conn_len > 1) { + /* select this DAC in the pin's input mux */ + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, j); - spec->multiout.num_dacs = cfg->line_outs; + } + } + snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", + spec->multiout.num_dacs, + spec->multiout.dac_nids[0], + spec->multiout.dac_nids[1], + spec->multiout.dac_nids[2], + spec->multiout.dac_nids[3], + spec->multiout.dac_nids[4]); return 0; } @@ -1204,12 +1259,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) { - int i; - - for (i = 0; i < spec->multiout.num_dacs; i++) { - if (spec->multiout.dac_nids[i] == nid) - return 1; - } + if (is_in_dac_nids(spec, nid)) + return 1; if (spec->multiout.hp_nid == nid) return 1; return 0; @@ -1251,12 +1302,10 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, add_spec_dacs(spec, nid); } for (i = 0; i < cfg->speaker_outs; i++) { - nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0, + nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; if (check_in_dac_nids(spec, nid)) nid = 0; - if (check_in_dac_nids(spec, nid)) - nid = 0; if (! nid) continue; add_spec_dacs(spec, nid); @@ -1370,7 +1419,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const imux->num_items++; } - if (imux->num_items == 1) { + if (imux->num_items) { /* * Set the current input for the muxes. * The STAC9221 has two input muxes with identical source @@ -1690,8 +1739,12 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, { unsigned int pin_ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); - if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN)) - return; + + /* if setting pin direction bits, clear the current + direction bits first */ + if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) + pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl | flag); -- cgit v0.10.2 From 2393144deac0903d944cbd578db49cf738811999 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Fri, 4 May 2007 09:35:54 +0200 Subject: [ALSA] wavefront: only declare isapnp on CONFIG_PNP From: David Rientjes isapnp[] is only used for CONFIG_PNP. If this configuration option is not set, do not declare the array. Cc: Adam Belay Cc: Takashi Iwai Signed-off-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Jaroslav Kysela diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index ae2038e..75673f7 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -40,7 +40,9 @@ MODULE_SUPPORTED_DEVICE("{{Turtle Beach,Maui/Tropez/Tropez+}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +#ifdef CONFIG_PNP static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +#endif static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */ static long cs4232_mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ -- cgit v0.10.2 From 713fb93936bebc158b4bbae6be61a6310923543c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 5 May 2007 12:02:25 +0200 Subject: [ALSA] wm8750 typo fix I quuestion the testing status of that patch! Signed-off-by: Andrew Morton Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 7073e8e..28684ee 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -808,7 +808,7 @@ static int wm8750_init(struct snd_soc_device *socdev) codec->dai = &wm8750_dai; codec->num_dai = 1; codec->reg_cache_size = sizeof(wm8750_reg); - codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KRENEL); + codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL); if (codec->reg_cache == NULL) return -ENOMEM; -- cgit v0.10.2 From 35b26722a1716b45b5b92d5af2f1ea1fdd4d0a25 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 5 May 2007 12:17:17 +0200 Subject: [ALSA] hda-codec - Fix AD1988 SPDIF playback route control Fix AD1988 SPDIF playback route control for selecting ADC1-3. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index f6f3c2c..0e1a879 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1898,8 +1898,9 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol, sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); if (sel > 0) { - sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0); - if (sel <= 3) + sel = snd_hda_codec_read(codec, 0x0b, 0, + AC_VERB_GET_CONNECT_SEL, 0); + if (sel < 3) sel++; else sel = 0; @@ -1912,23 +1913,27 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - unsigned int sel; + unsigned int val, sel; int change; + val = ucontrol->value.enumerated.item[0]; sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); - if (! ucontrol->value.enumerated.item[0]) { + if (!val) { change = sel != 0; - if (change) - snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0); + if (change || codec->in_resume) + snd_hda_codec_write(codec, 0x02, 0, + AC_VERB_SET_CONNECT_SEL, 0); } else { change = sel == 0; - if (change) - snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1); - sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1; - change |= sel == ucontrol->value.enumerated.item[0]; - if (change) - snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, - ucontrol->value.enumerated.item[0] - 1); + if (change || codec->in_resume) + snd_hda_codec_write(codec, 0x02, 0, + AC_VERB_SET_CONNECT_SEL, 1); + sel = snd_hda_codec_read(codec, 0x0b, 0, + AC_VERB_GET_CONNECT_SEL, 0) + 1; + change |= sel != val; + if (change || codec->in_resume) + snd_hda_codec_write(codec, 0x0b, 0, + AC_VERB_SET_CONNECT_SEL, val - 1); } return change; } -- cgit v0.10.2 From 458a4fabf185d90234225d7e05d81188b4dad9f1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 5 May 2007 12:18:40 +0200 Subject: [ALSA] hda-codec - Fix ALC880 uniwill auto-mutes Fix the auto-mute controls of ALC880 uniwill model. Split to two individual functions to handle HP and front-mic mutes. For front-mic mute, use snd_hda_codec_amp_update() to be consistent with mixer. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d9213fa..8c0b4fb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1487,7 +1487,7 @@ static struct hda_verb alc880_beep_init_verbs[] = { }; /* toggle speaker-output according to the hp-jack state */ -static void alc880_uniwill_automute(struct hda_codec *codec) +static void alc880_uniwill_hp_automute(struct hda_codec *codec) { unsigned int present; unsigned char bits; @@ -1503,11 +1503,27 @@ static void alc880_uniwill_automute(struct hda_codec *codec) 0x80, bits); snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, 0x80, bits); +} + +/* auto-toggle front mic */ +static void alc880_uniwill_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE, - 0x7000 | (0x01 << 8) | bits); + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, + 0x80, bits); +} + +static void alc880_uniwill_automute(struct hda_codec *codec) +{ + alc880_uniwill_hp_automute(codec); + alc880_uniwill_mic_automute(codec); } static void alc880_uniwill_unsol_event(struct hda_codec *codec, @@ -1516,9 +1532,14 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, /* Looks like the unsol event is incompatible with the standard * definition. 4bit tag is placed at 28 bit! */ - if ((res >> 28) == ALC880_HP_EVENT || - (res >> 28) == ALC880_MIC_EVENT) - alc880_uniwill_automute(codec); + switch (res >> 28) { + case ALC880_HP_EVENT: + alc880_uniwill_hp_automute(codec); + break; + case ALC880_MIC_EVENT: + alc880_uniwill_mic_automute(codec); + break; + } } static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) -- cgit v0.10.2 From d427c77eb2484c37d76b8e157e2b0b82c9b03062 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 5 May 2007 12:19:52 +0200 Subject: [ALSA] hda-codec - Fix a typo The AMP mute bit is bit 7. No real influence since no one uses this definition yet, though... Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index c12bc4e..56c26e7 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -233,7 +233,7 @@ enum { */ /* Amp gain/mute */ -#define AC_AMP_MUTE (1<<8) +#define AC_AMP_MUTE (1<<7) #define AC_AMP_GAIN (0x7f) #define AC_AMP_GET_INDEX (0xf<<0) -- cgit v0.10.2 From a91214589e6527b18f52bc0b31253f9dfb4665e6 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 7 May 2007 09:27:05 +0200 Subject: [ALSA] usb-audio: explicitly match Logitech QuickCam Commit 93c8bf45e083b89dffe3a708363c15c1b220c723 modified the USB device matching behaviour to ignore interface class matches if the device class is vendor-specific. This patch adds explicit ID matches for Logitech QuickCam devices, which have a vendor specific device class (but standards-compliant audio interfaces). This fixes a 2.6.20 regression where the audio component of these devices was no longer usable. http://bugs.gentoo.org/show_bug.cgi?id=175715 https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.20/+bug/93822 https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3040 Based on a patch from sergiom Signed-off-by: Daniel Drake Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 8582620..8fcbe93 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -40,6 +40,29 @@ .bInterfaceClass = USB_CLASS_VENDOR_SPEC /* + * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface + * class matches do not take effect without an explicit ID match. + */ +{ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS, + .idVendor = 0x046d, + .idProduct = 0x08f0, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL +}, +{ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS, + .idVendor = 0x046d, + .idProduct = 0x08f6, + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL +}, + +/* * Yamaha devices */ -- cgit v0.10.2 From d05cc104320210e1c38ff9675c5038cffb2d86dc Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 7 May 2007 09:28:53 +0200 Subject: [ALSA] usb-audio: work around broken M-Audio MidiSport Uno firmware The firmware of the M-Audio USB Uno MIDI Interface has, at least in hardware revision 1.25, a bug that garbles its USB output. When it receives a Note On MIDI message that uses running status, the resulting USB MIDI packet has a wrong CIN (4 instead of 9) and a wrong length (2 bytes, the status byte is still missing). This patch adds a workaround to track the CINs and the MIDI messages of received USB MIDI packets to detect whether a packet with CIN 4 is a correct SysEx packet or a buggy running status packet. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 24f5a26..911f448 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -1,7 +1,7 @@ /* * usbmidi.c - ALSA USB MIDI driver * - * Copyright (c) 2002-2005 Clemens Ladisch + * Copyright (c) 2002-2007 Clemens Ladisch * All rights reserved. * * Based on the OSS usb-midi driver by NAGANO Daisuke, @@ -145,6 +145,7 @@ struct snd_usb_midi_in_endpoint { struct urb* urb; struct usbmidi_in_port { struct snd_rawmidi_substream *substream; + u8 running_status_length; } ports[0x10]; u8 seen_f5; u8 error_resubmit; @@ -366,6 +367,46 @@ static void snd_usbmidi_midiman_input(struct snd_usb_midi_in_endpoint* ep, } /* + * Buggy M-Audio device: running status on input results in a packet that has + * the data bytes but not the status byte and that is marked with CIN 4. + */ +static void snd_usbmidi_maudio_broken_running_status_input( + struct snd_usb_midi_in_endpoint* ep, + uint8_t* buffer, int buffer_length) +{ + int i; + + for (i = 0; i + 3 < buffer_length; i += 4) + if (buffer[i] != 0) { + int cable = buffer[i] >> 4; + u8 cin = buffer[i] & 0x0f; + struct usbmidi_in_port *port = &ep->ports[cable]; + int length; + + length = snd_usbmidi_cin_length[cin]; + if (cin == 0xf && buffer[i + 1] >= 0xf8) + ; /* realtime msg: no running status change */ + else if (cin >= 0x8 && cin <= 0xe) + /* channel msg */ + port->running_status_length = length - 1; + else if (cin == 0x4 && + port->running_status_length != 0 && + buffer[i + 1] < 0x80) + /* CIN 4 that is not a SysEx */ + length = port->running_status_length; + else + /* + * All other msgs cannot begin running status. + * (A channel msg sent as two or three CIN 0xF + * packets could in theory, but this device + * doesn't use this format.) + */ + port->running_status_length = 0; + snd_usbmidi_input_data(ep, cable, &buffer[i + 1], length); + } +} + +/* * Adds one USB MIDI packet to the output buffer. */ static void snd_usbmidi_output_standard_packet(struct urb* urb, uint8_t p0, @@ -525,6 +566,12 @@ static struct usb_protocol_ops snd_usbmidi_midiman_ops = { .output_packet = snd_usbmidi_output_midiman_packet, }; +static struct usb_protocol_ops snd_usbmidi_maudio_broken_running_status_ops = { + .input = snd_usbmidi_maudio_broken_running_status_input, + .output = snd_usbmidi_standard_output, + .output_packet = snd_usbmidi_output_standard_packet, +}; + /* * Novation USB MIDI protocol: number of data bytes is in the first byte * (when receiving) (+1!) or in the second byte (when sending); data begins @@ -1606,6 +1653,9 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) { case QUIRK_MIDI_STANDARD_INTERFACE: err = snd_usbmidi_get_ms_info(umidi, endpoints); + if (chip->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */ + umidi->usb_protocol_ops = + &snd_usbmidi_maudio_broken_running_status_ops; break; case QUIRK_MIDI_FIXED_ENDPOINT: memcpy(&endpoints[0], quirk->data, -- cgit v0.10.2 From 490cbd92ed4d9915b582f4e40c605eeb977e5d40 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 7 May 2007 09:29:32 +0200 Subject: [ALSA] usb-audio: work around wrong wMaxPacketSize on ESI M4U Add a workaround for the ESI M4U that claims to support 32-byte packets but ignores the remaining bytes of packets bigger than four bytes. Signed-off-by: Clemens Ladisch Signed-off-by: Jaroslav Kysela diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 911f448..99295f9 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -965,7 +965,11 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, } /* we never use interrupt output pipes */ pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); - ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); + if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ + /* FIXME: we need more URBs to get reasonable bandwidth here: */ + ep->max_transfer = 4; + else + ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); buffer = usb_buffer_alloc(umidi->chip->dev, ep->max_transfer, GFP_KERNEL, &ep->urb->transfer_dma); if (!buffer) { -- cgit v0.10.2 From 0bbed758c024bb72cec8219879dc87cb04c6dd5c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 8 May 2007 15:17:15 +0200 Subject: [ALSA] hda-codec - Fix connection list in generic parser Fix the retrival of widget connection list in the generic parser. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 1e5ff0c..000287f 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -133,7 +133,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid return -ENOMEM; } } - memcpy(node->conn_list, conn_list, nconns); + memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t)); node->nconns = nconns; node->wid_caps = get_wcaps(codec, nid); node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; -- cgit v0.10.2 From bdd148a307e230517bf891c108e0eec68ba5d10f Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 8 May 2007 15:19:08 +0200 Subject: [ALSA] hda-codec - Add ALC861VD Lenovo support - Added ALC861VD Lenovo support (17aa:3802, 17aa:2066) - Modify alc_subsystem_id Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index d18e12b..57b878c 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -821,6 +821,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 6stack-dig 6-jack digital with SPDIF I/O arima Arima W820Di1 macpro MacPro support + w2jc ASUS W2JC auto auto-config reading BIOS (default) ALC883/888 @@ -852,6 +853,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 3stack-dig 3-jack with SPDIF OUT 6stack-dig 6-jack with SPDIF OUT 3stack-660 3-jack (for ALC660VD) + lenovo Lenovo 3000 C200 auto auto-config reading BIOS (default) CMI9880 diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8c0b4fb..a4ede27 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -117,6 +117,7 @@ enum { ALC861VD_3ST, ALC861VD_3ST_DIG, ALC861VD_6ST_DIG, + ALC861VD_LENOVO, ALC861VD_AUTO, ALC861VD_MODEL_LAST, }; @@ -137,6 +138,7 @@ enum { ALC882_3ST_DIG, ALC882_6ST_DIG, ALC882_ARIMA, + ALC882_W2JC, ALC882_AUTO, ALC885_MACPRO, ALC882_MODEL_LAST, @@ -635,6 +637,13 @@ static struct hda_verb alc_gpio2_init_verbs[] = { { } }; +static struct hda_verb alc_gpio3_init_verbs[] = { + {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, + { } +}; + /* 32-bit subsystem ID for BIOS loading in HD Audio codec. * 31 ~ 16 : Manufacture ID * 15 ~ 8 : SKU ID @@ -660,7 +669,22 @@ static void alc_subsystem_id(struct hda_codec *codec, case 3: snd_hda_sequence_write(codec, alc_gpio2_init_verbs); break; + case 7: + snd_hda_sequence_write(codec, alc_gpio3_init_verbs); + break; case 5: + switch (codec->vendor_id) { + case 0x10ec0862: + case 0x10ec0660: + case 0x10ec0662: + case 0x10ec0267: + case 0x10ec0268: + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_EAPD_BTLENABLE, 2); + snd_hda_codec_write(codec, 0x15, 0, + AC_VERB_SET_EAPD_BTLENABLE, 2); + return; + } case 6: if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */ hda_nid_t port = 0; @@ -4785,6 +4809,21 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc882_w2jc_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, 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("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + { } /* end */ +}; + static struct snd_kcontrol_new alc882_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -5104,6 +5143,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC882_3ST_DIG] = "3stack-dig", [ALC882_6ST_DIG] = "6stack-dig", [ALC882_ARIMA] = "arima", + [ALC882_W2JC] = "w2jc", [ALC885_MACPRO] = "macpro", [ALC882_AUTO] = "auto", }; @@ -5114,6 +5154,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), + SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), {} }; @@ -5150,6 +5191,18 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc882_sixstack_modes, .input_mux = &alc882_capture_source, }, + [ALC882_W2JC] = { + .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, + .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, + alc880_gpio1_init_verbs }, + .num_dacs = ARRAY_SIZE(alc882_dac_nids), + .dac_nids = alc882_dac_nids, + .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), + .channel_mode = alc880_threestack_modes, + .need_dac_fix = 1, + .input_mux = &alc882_capture_source, + .dig_out_nid = ALC882_DIGOUT_NID, + }, [ALC885_MACPRO] = { .mixers = { alc882_macpro_mixer }, .init_verbs = { alc882_macpro_init_verbs }, @@ -8708,6 +8761,27 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ + HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), + + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + + HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + + { } /* end */ +}; + /* * generic initialization of ADC, input mixers and output mixers */ @@ -8729,10 +8803,10 @@ static struct hda_verb alc861vd_volume_init_verbs[] = { {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)}, /* * Set up output mixers (0x02 - 0x05) @@ -8833,6 +8907,68 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = { { } }; +static struct hda_verb alc861vd_eapd_verbs[] = { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } +}; + +static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {} +}; + +/* toggle speaker-output according to the hp-jack state */ +static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, + 0x80, bits); +} + +static void alc861vd_lenovo_automute(struct hda_codec *codec) +{ + alc861vd_lenovo_hp_automute(codec); + alc861vd_lenovo_mic_automute(codec); +} + +static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc861vd_lenovo_hp_automute(codec); + break; + case ALC880_MIC_EVENT: + alc861vd_lenovo_mic_automute(codec); + break; + } +} + /* pcm configuration: identiacal with ALC880 */ #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture @@ -8847,6 +8983,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC861VD_3ST] = "3stack", [ALC861VD_3ST_DIG] = "3stack-digout", [ALC861VD_6ST_DIG] = "6stack-digout", + [ALC861VD_LENOVO] = "lenovo", [ALC861VD_AUTO] = "auto", }; @@ -8856,7 +8993,8 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), - SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST), + SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), + SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), {} }; @@ -8905,6 +9043,22 @@ static struct alc_config_preset alc861vd_presets[] = { .channel_mode = alc861vd_6stack_modes, .input_mux = &alc861vd_capture_source, }, + [ALC861VD_LENOVO] = { + .mixers = { alc861vd_lenovo_mixer }, + .init_verbs = { alc861vd_volume_init_verbs, + alc861vd_3stack_init_verbs, + alc861vd_eapd_verbs, + alc861vd_lenovo_unsol_verbs }, + .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), + .dac_nids = alc660vd_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), + .adc_nids = alc861vd_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), + .channel_mode = alc861vd_3stack_2ch_modes, + .input_mux = &alc861vd_capture_source, + .unsol_event = alc861vd_lenovo_unsol_event, + .init_hook = alc861vd_lenovo_automute, + }, }; /* @@ -9028,7 +9182,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, return err; sprintf(name, "%s Playback Switch", chname[i]); err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid_v, 3, 2, + HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); if (err < 0) return err; -- cgit v0.10.2 From 81937d3bac582ea2249dc2c8891d3371635e8b64 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Tue, 8 May 2007 15:33:03 +0200 Subject: [ALSA] Add speaker pin sequencing to hda_codec.c:snd_hda_parse_pin_def_config() Some verb tables (such as an Asus VT sent by IDT) contain only speaker outs in the default pin configs, and no line-outs. In such a case the speaker sequence numbers have to be used to order the speaker out pins, just as is being done for line-out pins. Then, when speaker-outs are copied to line-outs, the line-outs will be ordered properly. Signed-off-by: Steve Longerbeam Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ff12de4..14649d5 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2112,6 +2112,32 @@ static int __devinit is_in_nid_list(hda_nid_t nid, hda_nid_t *list) return 0; } + +/* + * Sort an associated group of pins according to their sequence numbers. + */ +static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, + int num_pins) +{ + int i, j; + short seq; + hda_nid_t nid; + + for (i = 0; i < num_pins; i++) { + for (j = i + 1; j < num_pins; j++) { + if (sequences[i] > sequences[j]) { + seq = sequences[i]; + sequences[i] = sequences[j]; + sequences[j] = seq; + nid = pins[i]; + pins[i] = pins[j]; + pins[j] = nid; + } + } + } +} + + /* * Parse all pin widgets and store the useful pin nids to cfg * @@ -2134,13 +2160,16 @@ int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, hda_nid_t *ignore_nids) { hda_nid_t nid, nid_start; - int i, j, nodes; - short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)]; + int nodes; + short seq, assoc_line_out, assoc_speaker; + short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; + short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; memset(cfg, 0, sizeof(*cfg)); - memset(sequences, 0, sizeof(sequences)); - assoc_line_out = 0; + memset(sequences_line_out, 0, sizeof(sequences_line_out)); + memset(sequences_speaker, 0, sizeof(sequences_speaker)); + assoc_line_out = assoc_speaker = 0; nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); for (nid = nid_start; nid < nodes + nid_start; nid++) { @@ -2175,13 +2204,22 @@ int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) continue; cfg->line_out_pins[cfg->line_outs] = nid; - sequences[cfg->line_outs] = seq; + sequences_line_out[cfg->line_outs] = seq; cfg->line_outs++; break; case AC_JACK_SPEAKER: + seq = get_defcfg_sequence(def_conf); + assoc = get_defcfg_association(def_conf); + if (! assoc) + continue; + if (! assoc_speaker) + assoc_speaker = assoc; + else if (assoc_speaker != assoc) + continue; if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) continue; cfg->speaker_pins[cfg->speaker_outs] = nid; + sequences_speaker[cfg->speaker_outs] = seq; cfg->speaker_outs++; break; case AC_JACK_HP_OUT: @@ -2227,16 +2265,32 @@ int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, } /* sort by sequence */ - for (i = 0; i < cfg->line_outs; i++) - for (j = i + 1; j < cfg->line_outs; j++) - if (sequences[i] > sequences[j]) { - seq = sequences[i]; - sequences[i] = sequences[j]; - sequences[j] = seq; - nid = cfg->line_out_pins[i]; - cfg->line_out_pins[i] = cfg->line_out_pins[j]; - cfg->line_out_pins[j] = nid; - } + sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out, + cfg->line_outs); + sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker, + cfg->speaker_outs); + + /* + * FIX-UP: if no line-outs are detected, try to use speaker or HP pin + * as a primary output + */ + if (!cfg->line_outs) { + if (cfg->speaker_outs) { + cfg->line_outs = cfg->speaker_outs; + memcpy(cfg->line_out_pins, cfg->speaker_pins, + sizeof(cfg->speaker_pins)); + cfg->speaker_outs = 0; + memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); + cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; + } else if (cfg->hp_outs) { + cfg->line_outs = cfg->hp_outs; + memcpy(cfg->line_out_pins, cfg->hp_pins, + sizeof(cfg->hp_pins)); + cfg->hp_outs = 0; + memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); + cfg->line_out_type = AUTO_PIN_HP_OUT; + } + } /* Reorder the surround channels * ALSA sequence is front/surr/clfe/side @@ -2278,28 +2332,6 @@ int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, cfg->input_pins[AUTO_PIN_CD], cfg->input_pins[AUTO_PIN_AUX]); - /* - * FIX-UP: if no line-outs are detected, try to use speaker or HP pin - * as a primary output - */ - if (!cfg->line_outs) { - if (cfg->speaker_outs) { - cfg->line_outs = cfg->speaker_outs; - memcpy(cfg->line_out_pins, cfg->speaker_pins, - sizeof(cfg->speaker_pins)); - cfg->speaker_outs = 0; - memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); - cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; - } else if (cfg->hp_outs) { - cfg->line_outs = cfg->hp_outs; - memcpy(cfg->line_out_pins, cfg->hp_pins, - sizeof(cfg->hp_pins)); - cfg->hp_outs = 0; - memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); - cfg->line_out_type = AUTO_PIN_HP_OUT; - } - } - return 0; } -- cgit v0.10.2 From c911d1e16dfc1f0338bbc245ff724322c0113395 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 11 May 2007 16:56:18 +0200 Subject: [ALSA] version 1.0.14rc4 Signed-off-by: Jaroslav Kysela diff --git a/include/sound/version.h b/include/sound/version.h index 42a18cc..e820f0e 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -1,3 +1,3 @@ /* include/version.h. Generated by alsa/ksync script. */ -#define CONFIG_SND_VERSION "1.0.14rc3" -#define CONFIG_SND_DATE " (Wed Mar 14 07:25:50 2007 UTC)" +#define CONFIG_SND_VERSION "1.0.14rc4" +#define CONFIG_SND_DATE " (Wed May 09 09:51:39 2007 UTC)" -- cgit v0.10.2