Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
Linus Torvalds [Wed, 7 Apr 2010 15:42:25 +0000 (08:42 -0700)]
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: mixart: range checking proc file
  ALSA: hda - Fix a wrong array range check in patch_realtek.c
  ALSA: ASoC: move dma_data from snd_soc_dai to snd_soc_pcm_stream
  ALSA: hda - Enable amplifiers on Acer Inspire 6530G
  ASoC: Only do WM8994 bias off transition from standby
  ASoC: Don't use DCS_DATAPATH_BUSY for WM hubs devices
  ASoC: Don't do runtime wm_hubs DC servo updates if using offset correction
  ASoC: Support second DC servo readback method for wm_hubs
  ASoC: Avoid wraparound in wm_hubs DC servo correction
  ALSA: echoaudio - Eliminate use after free
  ALSA: i2c: cleanup: change parameter to pointer
  ALSA: hda - Add MSI blacklist for Aopen MZ915-M
  ASoC: OMAP: Fix capture pointer handling for OMAP1510 to work correctly with recent ALSA PCM code
  ALSA: hda - Update document about MSI and interrupts
  ALSA: hda: Fix 0 dB offset for Lenovo Thinkpad models using AD1981
  ALSA: hda - Add missing printk argument in previous patch
  ASoC: Fix passing platform_data to ac97 bus users and fix a leak
  ALSA: hda - Fix ADC/MUX assignment of ALC269 codec
  ALSA: hda - Fix invalid bit values passed to snd_hda_codec_amp_stereo()
  ASoC: wm8994: playback => capture

1  2 
sound/pci/mixart/mixart.c
sound/soc/codecs/ac97.c
sound/soc/codecs/wm8994.c
sound/soc/davinci/davinci-i2s.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/imx/imx-pcm-dma-mx2.c
sound/soc/imx/imx-ssi.c
sound/soc/omap/omap-pcm.c
sound/soc/pxa/pxa-ssp.c
sound/soc/s6000/s6000-i2s.c
sound/soc/soc-core.c

@@@ -27,7 -27,6 +27,7 @@@
  #include <linux/dma-mapping.h>
  #include <linux/moduleparam.h>
  #include <linux/mutex.h>
 +#include <linux/slab.h>
  
  #include <sound/core.h>
  #include <sound/initval.h>
@@@ -1162,13 -1161,15 +1162,15 @@@ static long snd_mixart_BA0_read(struct 
                                unsigned long count, unsigned long pos)
  {
        struct mixart_mgr *mgr = entry->private_data;
+       unsigned long maxsize;
  
-       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
-       if(count <= 0)
+       if (pos >= MIXART_BA0_SIZE)
                return 0;
-       if(pos + count > MIXART_BA0_SIZE)
-               count = (long)(MIXART_BA0_SIZE - pos);
-       if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count))
+       maxsize = MIXART_BA0_SIZE - pos;
+       if (count > maxsize)
+               count = maxsize;
+       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
+       if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
                return -EFAULT;
        return count;
  }
@@@ -1181,13 -1182,15 +1183,15 @@@ static long snd_mixart_BA1_read(struct 
                                unsigned long count, unsigned long pos)
  {
        struct mixart_mgr *mgr = entry->private_data;
+       unsigned long maxsize;
  
-       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
-       if(count <= 0)
+       if (pos > MIXART_BA1_SIZE)
                return 0;
-       if(pos + count > MIXART_BA1_SIZE)
-               count = (long)(MIXART_BA1_SIZE - pos);
-       if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count))
+       maxsize = MIXART_BA1_SIZE - pos;
+       if (count > maxsize)
+               count = maxsize;
+       count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
+       if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
                return -EFAULT;
        return count;
  }
diff --combined sound/soc/codecs/ac97.c
@@@ -13,7 -13,6 +13,7 @@@
   */
  
  #include <linux/init.h>
 +#include <linux/slab.h>
  #include <linux/kernel.h>
  #include <linux/device.h>
  #include <sound/core.h>
@@@ -81,9 -80,11 +81,11 @@@ static int ac97_write(struct snd_soc_co
  static int ac97_soc_probe(struct platform_device *pdev)
  {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_card *card = socdev->card;
        struct snd_soc_codec *codec;
        struct snd_ac97_bus *ac97_bus;
        struct snd_ac97_template ac97_template;
+       int i;
        int ret = 0;
  
        printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
        INIT_LIST_HEAD(&codec->dapm_widgets);
        INIT_LIST_HEAD(&codec->dapm_paths);
  
-       ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
-       if (ret < 0) {
-               printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n");
-               goto err;
-       }
        /* register pcms */
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
        if (ret < 0)
        if (ret < 0)
                goto bus_err;
  
+       for (i = 0; i < card->num_links; i++) {
+               if (card->dai_link[i].codec_dai->ac97_control) {
+                       snd_ac97_dev_add_pdata(codec->ac97,
+                               card->dai_link[i].cpu_dai->ac97_pdata);
+               }
+       }
        return 0;
  
  bus_err:
@@@ -19,7 -19,6 +19,7 @@@
  #include <linux/i2c.h>
  #include <linux/platform_device.h>
  #include <linux/regulator/consumer.h>
 +#include <linux/slab.h>
  #include <sound/core.h>
  #include <sound/pcm.h>
  #include <sound/pcm_params.h>
@@@ -3008,34 -3007,39 +3008,39 @@@ static int wm8994_set_bias_level(struc
                break;
  
        case SND_SOC_BIAS_OFF:
-               /* Switch over to startup biases */
-               snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-                                   WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
-                                   WM8994_VMID_BUF_ENA |
-                                   WM8994_VMID_RAMP_MASK,
-                                   WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
-                                   WM8994_VMID_BUF_ENA |
-                                   (1 << WM8994_VMID_RAMP_SHIFT));
-               /* Disable main biases */
-               snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
-                                   WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
+               if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
+                       /* Switch over to startup biases */
+                       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+                                           WM8994_BIAS_SRC |
+                                           WM8994_STARTUP_BIAS_ENA |
+                                           WM8994_VMID_BUF_ENA |
+                                           WM8994_VMID_RAMP_MASK,
+                                           WM8994_BIAS_SRC |
+                                           WM8994_STARTUP_BIAS_ENA |
+                                           WM8994_VMID_BUF_ENA |
+                                           (1 << WM8994_VMID_RAMP_SHIFT));
  
-               /* Discharge line */
-               snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
-                                   WM8994_LINEOUT1_DISCH |
-                                   WM8994_LINEOUT2_DISCH,
-                                   WM8994_LINEOUT1_DISCH |
-                                   WM8994_LINEOUT2_DISCH);
+                       /* Disable main biases */
+                       snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
+                                           WM8994_BIAS_ENA |
+                                           WM8994_VMID_SEL_MASK, 0);
  
-               msleep(5);
+                       /* Discharge line */
+                       snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
+                                           WM8994_LINEOUT1_DISCH |
+                                           WM8994_LINEOUT2_DISCH,
+                                           WM8994_LINEOUT1_DISCH |
+                                           WM8994_LINEOUT2_DISCH);
  
-               /* Switch off startup biases */
-               snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
-                                   WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
-                                   WM8994_VMID_BUF_ENA |
-                                   WM8994_VMID_RAMP_MASK, 0);
+                       msleep(5);
  
+                       /* Switch off startup biases */
+                       snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
+                                           WM8994_BIAS_SRC |
+                                           WM8994_STARTUP_BIAS_ENA |
+                                           WM8994_VMID_BUF_ENA |
+                                           WM8994_VMID_RAMP_MASK, 0);
+               }
                break;
        }
        codec->bias_level = level;
@@@ -3402,7 -3406,7 +3407,7 @@@ struct snd_soc_dai wm8994_dai[] = 
                        .rates = WM8994_RATES,
                        .formats = WM8994_FORMATS,
                },
-               .playback = {
+               .capture = {
                        .stream_name = "AIF3 Capture",
                        .channels_min = 2,
                        .channels_max = 2,
@@@ -3731,11 -3735,12 +3736,12 @@@ static int wm8994_codec_probe(struct pl
        case 3:
                wm8994->hubs.dcs_codes = -5;
                wm8994->hubs.hp_startup_mode = 1;
+               wm8994->hubs.dcs_readback_mode = 1;
                break;
        default:
+               wm8994->hubs.dcs_readback_mode = 1;
                break;
        }
-                          
  
        /* Remember if AIFnLRCLK is configured as a GPIO.  This should be
         * configured on init - if a system wants to do this dynamically
@@@ -12,7 -12,6 +12,7 @@@
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/device.h>
 +#include <linux/slab.h>
  #include <linux/delay.h>
  #include <linux/io.h>
  #include <linux/clk.h>
@@@ -586,7 -585,8 +586,8 @@@ static int davinci_i2s_probe(struct pla
        dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
  
        davinci_i2s_dai.private_data = dev;
-       davinci_i2s_dai.dma_data = dev->dma_params;
+       davinci_i2s_dai.capture.dma_data = dev->dma_params;
+       davinci_i2s_dai.playback.dma_data = dev->dma_params;
        ret = snd_soc_register_dai(&davinci_i2s_dai);
        if (ret != 0)
                goto err_free_mem;
@@@ -18,7 -18,6 +18,7 @@@
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/device.h>
 +#include <linux/slab.h>
  #include <linux/delay.h>
  #include <linux/io.h>
  #include <linux/clk.h>
@@@ -918,7 -917,8 +918,8 @@@ static int davinci_mcasp_probe(struct p
  
        dma_data->channel = res->start;
        davinci_mcasp_dai[pdata->op_mode].private_data = dev;
-       davinci_mcasp_dai[pdata->op_mode].dma_data = dev->dma_params;
+       davinci_mcasp_dai[pdata->op_mode].capture.dma_data = dev->dma_params;
+       davinci_mcasp_dai[pdata->op_mode].playback.dma_data = dev->dma_params;
        davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
        ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
  
@@@ -19,7 -19,6 +19,7 @@@
  #include <linux/interrupt.h>
  #include <linux/module.h>
  #include <linux/platform_device.h>
 +#include <linux/slab.h>
  
  #include <sound/core.h>
  #include <sound/initval.h>
@@@ -84,11 -83,13 +84,13 @@@ static void snd_imx_dma_err_callback(in
  static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
  {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+       struct imx_pcm_dma_params *dma_params;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
        int ret;
  
+       dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
        iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
        if (iprtd->dma < 0) {
                pr_err("Failed to claim the audio DMA\n");
@@@ -193,10 -194,12 +195,12 @@@ static int snd_imx_pcm_prepare(struct s
  {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+       struct imx_pcm_dma_params *dma_params;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
        int err;
  
+       dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
        iprtd->substream = substream;
        iprtd->buf = (unsigned int *)substream->dma_buffer.area;
        iprtd->period_cnt = 0;
diff --combined sound/soc/imx/imx-ssi.c
@@@ -39,7 -39,6 +39,7 @@@
  #include <linux/interrupt.h>
  #include <linux/module.h>
  #include <linux/platform_device.h>
 +#include <linux/slab.h>
  
  #include <sound/core.h>
  #include <sound/initval.h>
@@@ -235,17 -234,20 +235,20 @@@ static int imx_ssi_hw_params(struct snd
                             struct snd_soc_dai *cpu_dai)
  {
        struct imx_ssi *ssi = cpu_dai->private_data;
+       struct imx_pcm_dma_params *dma_data;
        u32 reg, sccr;
  
        /* Tx/Rx config */
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                reg = SSI_STCCR;
-               cpu_dai->dma_data = &ssi->dma_params_tx;
+               dma_data = &ssi->dma_params_tx;
        } else {
                reg = SSI_SRCCR;
-               cpu_dai->dma_data = &ssi->dma_params_rx;
+               dma_data = &ssi->dma_params_rx;
        }
  
+       snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
        sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
  
        /* DAI data (word) size */
@@@ -23,7 -23,6 +23,7 @@@
   */
  
  #include <linux/dma-mapping.h>
 +#include <linux/slab.h>
  #include <sound/core.h>
  #include <sound/pcm.h>
  #include <sound/pcm_params.h>
@@@ -61,12 -60,11 +61,11 @@@ static void omap_pcm_dma_irq(int ch, u1
        struct omap_runtime_data *prtd = runtime->private_data;
        unsigned long flags;
  
-       if ((cpu_is_omap1510()) &&
-                       (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
+       if ((cpu_is_omap1510())) {
                /*
                 * OMAP1510 doesn't fully support DMA progress counter
                 * and there is no software emulation implemented yet,
-                * so have to maintain our own playback progress counter
+                * so have to maintain our own progress counters
                 * that can be used by omap_pcm_pointer() instead.
                 */
                spin_lock_irqsave(&prtd->lock, flags);
@@@ -101,9 -99,11 +100,11 @@@ static int omap_pcm_hw_params(struct sn
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct omap_runtime_data *prtd = runtime->private_data;
-       struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data;
+       struct omap_pcm_dma_data *dma_data;
        int err = 0;
  
+       dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
        /* return if this is a bufferless transfer e.g.
         * codec <--> BT codec or GSM modem -- lg FIXME */
        if (!dma_data)
@@@ -190,8 -190,7 +191,7 @@@ static int omap_pcm_prepare(struct snd_
        dma_params.frame_count  = runtime->periods;
        omap_set_dma_params(prtd->dma_ch, &dma_params);
  
-       if ((cpu_is_omap1510()) &&
-                       (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
+       if ((cpu_is_omap1510()))
                omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
                              OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
        else
@@@ -249,14 -248,15 +249,15 @@@ static snd_pcm_uframes_t omap_pcm_point
        dma_addr_t ptr;
        snd_pcm_uframes_t offset;
  
-       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+       if (cpu_is_omap1510()) {
+               offset = prtd->period_index * runtime->period_size;
+       } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
                ptr = omap_get_dma_dst_pos(prtd->dma_ch);
                offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
-       } else if (!(cpu_is_omap1510())) {
+       } else {
                ptr = omap_get_dma_src_pos(prtd->dma_ch);
                offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
-       } else
-               offset = prtd->period_index * runtime->period_size;
+       }
  
        if (offset >= runtime->buffer_size)
                offset = 0;
diff --combined sound/soc/pxa/pxa-ssp.c
@@@ -16,7 -16,6 +16,7 @@@
  
  #include <linux/init.h>
  #include <linux/module.h>
 +#include <linux/slab.h>
  #include <linux/platform_device.h>
  #include <linux/clk.h>
  #include <linux/io.h>
@@@ -122,10 -121,9 +122,9 @@@ static int pxa_ssp_startup(struct snd_p
                ssp_disable(ssp);
        }
  
-       if (cpu_dai->dma_data) {
-               kfree(cpu_dai->dma_data);
-               cpu_dai->dma_data = NULL;
-       }
+       kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
+       snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
        return ret;
  }
  
@@@ -142,10 -140,8 +141,8 @@@ static void pxa_ssp_shutdown(struct snd
                clk_disable(ssp->clk);
        }
  
-       if (cpu_dai->dma_data) {
-               kfree(cpu_dai->dma_data);
-               cpu_dai->dma_data = NULL;
-       }
+       kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
+       snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
  }
  
  #ifdef CONFIG_PM
@@@ -570,19 -566,23 +567,23 @@@ static int pxa_ssp_hw_params(struct snd
        u32 sspsp;
        int width = snd_pcm_format_physical_width(params_format(params));
        int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
+       struct pxa2xx_pcm_dma_params *dma_data;
+       dma_data = snd_soc_dai_get_dma_data(dai, substream);
  
        /* generate correct DMA params */
-       if (cpu_dai->dma_data)
-               kfree(cpu_dai->dma_data);
+       kfree(dma_data);
  
        /* Network mode with one active slot (ttsa == 1) can be used
         * to force 16-bit frame width on the wire (for S16_LE), even
         * with two channels. Use 16-bit DMA transfers for this case.
         */
-       cpu_dai->dma_data = ssp_get_dma_params(ssp,
+       dma_data = ssp_get_dma_params(ssp,
                        ((chn == 2) && (ttsa != 1)) || (width == 32),
                        substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
  
+       snd_soc_dai_set_dma_data(dai, substream, dma_data);
        /* we can only change the settings if the port is not in use */
        if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
                return 0;
@@@ -16,7 -16,6 +16,7 @@@
  #include <linux/clk.h>
  #include <linux/interrupt.h>
  #include <linux/io.h>
 +#include <linux/slab.h>
  
  #include <sound/core.h>
  #include <sound/pcm.h>
@@@ -519,7 -518,8 +519,8 @@@ static int __devinit s6000_i2s_probe(st
  
        s6000_i2s_dai.dev = &pdev->dev;
        s6000_i2s_dai.private_data = dev;
-       s6000_i2s_dai.dma_data = &dev->dma_params;
+       s6000_i2s_dai.capture.dma_data = &dev->dma_params;
+       s6000_i2s_dai.playback.dma_data = &dev->dma_params;
  
        dev->sifbase = sifmem->start;
        dev->scbbase = mmio;
diff --combined sound/soc/soc-core.c
@@@ -28,7 -28,6 +28,7 @@@
  #include <linux/bitops.h>
  #include <linux/debugfs.h>
  #include <linux/platform_device.h>
 +#include <linux/slab.h>
  #include <sound/ac97_codec.h>
  #include <sound/core.h>
  #include <sound/pcm.h>
@@@ -1549,7 -1548,8 +1549,8 @@@ int snd_soc_new_pcms(struct snd_soc_dev
                        mutex_unlock(&codec->mutex);
                        return ret;
                }
-               if (card->dai_link[i].codec_dai->ac97_control) {
+               /* Check for codec->ac97 to handle the ac97.c fun */
+               if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) {
                        snd_ac97_dev_add_pdata(codec->ac97,
                                card->dai_link[i].cpu_dai->ac97_pdata);
                }