Merge branch 'fix/misc' into for-linus
authorTakashi Iwai <tiwai@suse.de>
Mon, 21 Dec 2009 11:05:40 +0000 (12:05 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 21 Dec 2009 11:05:40 +0000 (12:05 +0100)
sound/arm/aaci.c
sound/arm/aaci.h
sound/core/pcm_lib.c
sound/isa/msnd/msnd_midi.c
sound/isa/sb/emu8000.c
sound/mips/sgio2audio.c
sound/oss/pss.c
sound/pci/hda/patch_realtek.c
sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
sound/usb/usbaudio.c

index 1497dce..c569986 100644 (file)
@@ -172,14 +172,15 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
        return v;
 }
 
-static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun)
+static inline void
+aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask)
 {
        u32 val;
        int timeout = 5000;
 
        do {
                val = readl(aacirun->base + AACI_SR);
-       } while (val & (SR_TXB|SR_RXB) && timeout--);
+       } while (val & mask && timeout--);
 }
 
 
@@ -208,8 +209,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                        writel(0, aacirun->base + AACI_IE);
                        return;
                }
-               ptr = aacirun->ptr;
 
+               spin_lock(&aacirun->lock);
+
+               ptr = aacirun->ptr;
                do {
                        unsigned int len = aacirun->fifosz;
                        u32 val;
@@ -217,9 +220,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                        if (aacirun->bytes <= 0) {
                                aacirun->bytes += aacirun->period;
                                aacirun->ptr = ptr;
-                               spin_unlock(&aaci->lock);
+                               spin_unlock(&aacirun->lock);
                                snd_pcm_period_elapsed(aacirun->substream);
-                               spin_lock(&aaci->lock);
+                               spin_lock(&aacirun->lock);
                        }
                        if (!(aacirun->cr & CR_EN))
                                break;
@@ -245,7 +248,10 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                                        ptr = aacirun->start;
                        }
                } while(1);
+
                aacirun->ptr = ptr;
+
+               spin_unlock(&aacirun->lock);
        }
 
        if (mask & ISR_URINTR) {
@@ -263,6 +269,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                        return;
                }
 
+               spin_lock(&aacirun->lock);
+
                ptr = aacirun->ptr;
                do {
                        unsigned int len = aacirun->fifosz;
@@ -271,9 +279,9 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                        if (aacirun->bytes <= 0) {
                                aacirun->bytes += aacirun->period;
                                aacirun->ptr = ptr;
-                               spin_unlock(&aaci->lock);
+                               spin_unlock(&aacirun->lock);
                                snd_pcm_period_elapsed(aacirun->substream);
-                               spin_lock(&aaci->lock);
+                               spin_lock(&aacirun->lock);
                        }
                        if (!(aacirun->cr & CR_EN))
                                break;
@@ -301,6 +309,8 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
                } while (1);
 
                aacirun->ptr = ptr;
+
+               spin_unlock(&aacirun->lock);
        }
 }
 
@@ -310,7 +320,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
        u32 mask;
        int i;
 
-       spin_lock(&aaci->lock);
        mask = readl(aaci->base + AACI_ALLINTS);
        if (mask) {
                u32 m = mask;
@@ -320,7 +329,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
                        }
                }
        }
-       spin_unlock(&aaci->lock);
 
        return mask ? IRQ_HANDLED : IRQ_NONE;
 }
@@ -330,63 +338,6 @@ static irqreturn_t aaci_irq(int irq, void *devid)
 /*
  * ALSA support.
  */
-
-struct aaci_stream {
-       unsigned char codec_idx;
-       unsigned char rate_idx;
-};
-
-static struct aaci_stream aaci_streams[] = {
-       [ACSTREAM_FRONT] = {
-               .codec_idx      = 0,
-               .rate_idx       = AC97_RATES_FRONT_DAC,
-       },
-       [ACSTREAM_SURROUND] = {
-               .codec_idx      = 0,
-               .rate_idx       = AC97_RATES_SURR_DAC,
-       },
-       [ACSTREAM_LFE] = {
-               .codec_idx      = 0,
-               .rate_idx       = AC97_RATES_LFE_DAC,
-       },
-};
-
-static inline unsigned int aaci_rate_mask(struct aaci *aaci, int streamid)
-{
-       struct aaci_stream *s = aaci_streams + streamid;
-       return aaci->ac97_bus->codec[s->codec_idx]->rates[s->rate_idx];
-}
-
-static unsigned int rate_list[] = {
-       5512, 8000, 11025, 16000, 22050, 32000, 44100,
-       48000, 64000, 88200, 96000, 176400, 192000
-};
-
-/*
- * Double-rate rule: we can support double rate iff channels == 2
- *  (unimplemented)
- */
-static int
-aaci_rule_rate_by_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule)
-{
-       struct aaci *aaci = rule->private;
-       unsigned int rate_mask = SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_5512;
-       struct snd_interval *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS);
-
-       switch (c->max) {
-       case 6:
-               rate_mask &= aaci_rate_mask(aaci, ACSTREAM_LFE);
-       case 4:
-               rate_mask &= aaci_rate_mask(aaci, ACSTREAM_SURROUND);
-       case 2:
-               rate_mask &= aaci_rate_mask(aaci, ACSTREAM_FRONT);
-       }
-
-       return snd_interval_list(hw_param_interval(p, rule->var),
-                                ARRAY_SIZE(rate_list), rate_list,
-                                rate_mask);
-}
-
 static struct snd_pcm_hardware aaci_hw_info = {
        .info                   = SNDRV_PCM_INFO_MMAP |
                                  SNDRV_PCM_INFO_MMAP_VALID |
@@ -400,10 +351,7 @@ static struct snd_pcm_hardware aaci_hw_info = {
         */
        .formats                = SNDRV_PCM_FMTBIT_S16_LE,
 
-       /* should this be continuous or knot? */
-       .rates                  = SNDRV_PCM_RATE_CONTINUOUS,
-       .rate_max               = 48000,
-       .rate_min               = 4000,
+       /* rates are setup from the AC'97 codec */
        .channels_min           = 2,
        .channels_max           = 6,
        .buffer_bytes_max       = 64 * 1024,
@@ -423,6 +371,12 @@ static int __aaci_pcm_open(struct aaci *aaci,
        aacirun->substream = substream;
        runtime->private_data = aacirun;
        runtime->hw = aaci_hw_info;
+       runtime->hw.rates = aacirun->pcm->rates;
+       snd_pcm_limit_hw_rates(runtime);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
+           aacirun->pcm->r[1].slots)
+               snd_ac97_pcm_double_rate_rules(runtime);
 
        /*
         * FIXME: ALSA specifies fifo_size in bytes.  If we're in normal
@@ -433,17 +387,6 @@ static int __aaci_pcm_open(struct aaci *aaci,
         */
        runtime->hw.fifo_size = aaci->fifosize * 2;
 
-       /*
-        * Add rule describing hardware rate dependency
-        * on the number of channels.
-        */
-       ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
-                                 aaci_rule_rate_by_channels, aaci,
-                                 SNDRV_PCM_HW_PARAM_CHANNELS,
-                                 SNDRV_PCM_HW_PARAM_RATE, -1);
-       if (ret)
-               goto out;
-
        ret = request_irq(aaci->dev->irq[0], aaci_irq, IRQF_SHARED|IRQF_DISABLED,
                          DRIVER_NAME, aaci);
        if (ret)
@@ -507,18 +450,22 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
 
        err = snd_pcm_lib_malloc_pages(substream,
                                       params_buffer_bytes(params));
-       if (err < 0)
-               goto out;
+       if (err >= 0) {
+               unsigned int rate = params_rate(params);
+               int dbl = rate > 48000;
 
-       err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
-                               params_channels(params),
-                               aacirun->pcm->r[0].slots);
-       if (err)
-               goto out;
+               err = snd_ac97_pcm_open(aacirun->pcm, rate,
+                                       params_channels(params),
+                                       aacirun->pcm->r[dbl].slots);
 
-       aacirun->pcm_open = 1;
+               aacirun->pcm_open = err == 0;
+               aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
+               aacirun->fifosz = aaci->fifosize * 4;
+
+               if (aacirun->cr & CR_COMPACT)
+                       aacirun->fifosz >>= 1;
+       }
 
- out:
        return err;
 }
 
@@ -527,7 +474,7 @@ static int aaci_pcm_prepare(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct aaci_runtime *aacirun = runtime->private_data;
 
-       aacirun->start  = (void *)runtime->dma_area;
+       aacirun->start  = runtime->dma_area;
        aacirun->end    = aacirun->start + snd_pcm_lib_buffer_bytes(substream);
        aacirun->ptr    = aacirun->start;
        aacirun->period =
@@ -627,14 +574,9 @@ static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
         * Enable FIFO, compact mode, 16 bits per sample.
         * FIXME: double rate slots?
         */
-       if (ret >= 0) {
-               aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
+       if (ret >= 0)
                aacirun->cr |= channels_to_txmask[channels];
 
-               aacirun->fifosz = aaci->fifosize * 4;
-               if (aacirun->cr & CR_COMPACT)
-                       aacirun->fifosz >>= 1;
-       }
        return ret;
 }
 
@@ -646,7 +588,7 @@ static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun)
        ie &= ~(IE_URIE|IE_TXIE);
        writel(ie, aacirun->base + AACI_IE);
        aacirun->cr &= ~CR_EN;
-       aaci_chan_wait_ready(aacirun);
+       aaci_chan_wait_ready(aacirun, SR_TXB);
        writel(aacirun->cr, aacirun->base + AACI_TXCR);
 }
 
@@ -654,7 +596,7 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
 {
        u32 ie;
 
-       aaci_chan_wait_ready(aacirun);
+       aaci_chan_wait_ready(aacirun, SR_TXB);
        aacirun->cr |= CR_EN;
 
        ie = readl(aacirun->base + AACI_IE);
@@ -665,12 +607,12 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
 
 static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-       struct aaci *aaci = substream->private_data;
        struct aaci_runtime *aacirun = substream->runtime->private_data;
        unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(&aaci->lock, flags);
+       spin_lock_irqsave(&aacirun->lock, flags);
+
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
                aaci_pcm_playback_start(aacirun);
@@ -697,7 +639,8 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm
        default:
                ret = -EINVAL;
        }
-       spin_unlock_irqrestore(&aaci->lock, flags);
+
+       spin_unlock_irqrestore(&aacirun->lock, flags);
 
        return ret;
 }
@@ -721,18 +664,10 @@ static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream,
        int ret;
 
        ret = aaci_pcm_hw_params(substream, aacirun, params);
-
-       if (ret >= 0) {
-               aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
-
+       if (ret >= 0)
                /* Line in record: slot 3 and 4 */
                aacirun->cr |= CR_SL3 | CR_SL4;
 
-               aacirun->fifosz = aaci->fifosize * 4;
-
-               if (aacirun->cr & CR_COMPACT)
-                       aacirun->fifosz >>= 1;
-       }
        return ret;
 }
 
@@ -740,7 +675,7 @@ static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun)
 {
        u32 ie;
 
-       aaci_chan_wait_ready(aacirun);
+       aaci_chan_wait_ready(aacirun, SR_RXB);
 
        ie = readl(aacirun->base + AACI_IE);
        ie &= ~(IE_ORIE | IE_RXIE);
@@ -755,7 +690,7 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
 {
        u32 ie;
 
-       aaci_chan_wait_ready(aacirun);
+       aaci_chan_wait_ready(aacirun, SR_RXB);
 
 #ifdef DEBUG
        /* RX Timeout value: bits 28:17 in RXCR */
@@ -772,12 +707,11 @@ static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
 
 static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-       struct aaci *aaci = substream->private_data;
        struct aaci_runtime *aacirun = substream->runtime->private_data;
        unsigned long flags;
        int ret = 0;
 
-       spin_lock_irqsave(&aaci->lock, flags);
+       spin_lock_irqsave(&aacirun->lock, flags);
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
@@ -806,7 +740,7 @@ static int aaci_pcm_capture_trigger(struct snd_pcm_substream *substream, int cmd
                ret = -EINVAL;
        }
 
-       spin_unlock_irqrestore(&aaci->lock, flags);
+       spin_unlock_irqrestore(&aacirun->lock, flags);
 
        return ret;
 }
@@ -889,6 +823,12 @@ static struct ac97_pcm ac97_defs[] __devinitdata = {
                                          (1 << AC97_SLOT_PCM_SRIGHT) |
                                          (1 << AC97_SLOT_LFE),
                        },
+                       [1] = {
+                               .slots  = (1 << AC97_SLOT_PCM_LEFT) |
+                                         (1 << AC97_SLOT_PCM_RIGHT) |
+                                         (1 << AC97_SLOT_PCM_LEFT_0) |
+                                         (1 << AC97_SLOT_PCM_RIGHT_0),
+                       },
                },
        },
        [1] = { /* PCM in */
@@ -1001,7 +941,6 @@ static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
 
        aaci = card->private_data;
        mutex_init(&aaci->ac97_sem);
-       spin_lock_init(&aaci->lock);
        aaci->card = card;
        aaci->dev = dev;
 
@@ -1028,7 +967,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
                snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-                                                     NULL, 0, 64 * 104);
+                                                     NULL, 0, 64 * 1024);
        }
 
        return ret;
@@ -1088,12 +1027,14 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
        /*
         * Playback uses AACI channel 0
         */
+       spin_lock_init(&aaci->playback.lock);
        aaci->playback.base = aaci->base + AACI_CSCH1;
        aaci->playback.fifo = aaci->base + AACI_DR1;
 
        /*
         * Capture uses AACI channel 0
         */
+       spin_lock_init(&aaci->capture.lock);
        aaci->capture.base = aaci->base + AACI_CSCH1;
        aaci->capture.fifo = aaci->base + AACI_DR1;
 
index 924f69c..6a4a2ee 100644 (file)
 struct aaci_runtime {
        void                    __iomem *base;
        void                    __iomem *fifo;
+       spinlock_t              lock;
 
        struct ac97_pcm         *pcm;
        int                     pcm_open;
@@ -232,7 +233,6 @@ struct aaci {
        struct snd_ac97         *ac97;
 
        u32                     maincr;
-       spinlock_t              lock;
 
        struct aaci_runtime     playback;
        struct aaci_runtime     capture;
index 30f4108..a27545b 100644 (file)
@@ -758,7 +758,7 @@ int snd_interval_ratnum(struct snd_interval *i,
                int diff;
                if (q == 0)
                        q = 1;
-               den = div_down(num, q);
+               den = div_up(num, q);
                if (den < rats[k].den_min)
                        continue;
                if (den > rats[k].den_max)
@@ -794,7 +794,7 @@ int snd_interval_ratnum(struct snd_interval *i,
                        i->empty = 1;
                        return -EINVAL;
                }
-               den = div_up(num, q);
+               den = div_down(num, q);
                if (den > rats[k].den_max)
                        continue;
                if (den < rats[k].den_min)
index cb9aa4c..4be562b 100644 (file)
@@ -162,7 +162,7 @@ int snd_msndmidi_new(struct snd_card *card, int device)
        err = snd_rawmidi_new(card, "MSND-MIDI", device, 1, 1, &rmidi);
        if (err < 0)
                return err;
-       mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL);
+       mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
        if (mpu == NULL) {
                snd_device_free(card, rmidi);
                return -ENOMEM;
index 96678d5..751762f 100644 (file)
@@ -393,8 +393,6 @@ size_dram(struct snd_emu8000 *emu)
 
        while (size < EMU8000_MAX_DRAM) {
 
-               size += 512 * 1024;  /* increment 512kbytes */
-
                /* Write a unique data on the test address.
                 * if the address is out of range, the data is written on
                 * 0x200000(=EMU8000_DRAM_OFFSET).  Then the id word is
@@ -414,7 +412,9 @@ size_dram(struct snd_emu8000 *emu)
                /*snd_emu8000_read_wait(emu);*/
                EMU8000_SMLD_READ(emu); /* discard stale data  */
                if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)
-                       break; /* we must have wrapped around */
+                       break; /* no memory at this address */
+
+               size += 512 * 1024;  /* increment 512kbytes */
 
                snd_emu8000_read_wait(emu);
 
index 8691f4c..f1d9d16 100644 (file)
@@ -609,7 +609,7 @@ static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream,
        /* alloc virtual 'dma' area */
        if (runtime->dma_area)
                vfree(runtime->dma_area);
-       runtime->dma_area = vmalloc(size);
+       runtime->dma_area = vmalloc_user(size);
        if (runtime->dma_area == NULL)
                return -ENOMEM;
        runtime->dma_bytes = size;
index 83f5ee2..e19dd5d 100644 (file)
@@ -269,7 +269,7 @@ static int pss_reset_dsp(pss_confdata * devc)
        unsigned long   i, limit = jiffies + HZ/10;
 
        outw(0x2000, REG(PSS_CONTROL));
-       for (i = 0; i < 32768 && (limit-jiffies >= 0); i++)
+       for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
                inw(REG(PSS_CONTROL));
        outw(0x0000, REG(PSS_CONTROL));
        return 1;
@@ -369,11 +369,11 @@ static int pss_download_boot(pss_confdata * devc, unsigned char *block, int size
                outw(0, REG(PSS_DATA));
 
                limit = jiffies + HZ/10;
-               for (i = 0; i < 32768 && (limit - jiffies >= 0); i++)
+               for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
                        val = inw(REG(PSS_STATUS));
 
                limit = jiffies + HZ/10;
-               for (i = 0; i < 32768 && (limit-jiffies >= 0); i++)
+               for (i = 0; i < 32768 && time_after_eq(limit, jiffies); i++)
                {
                        val = inw(REG(PSS_STATUS));
                        if (val & 0x4000)
index 0877bae..c746505 100644 (file)
@@ -12924,7 +12924,7 @@ static int patch_alc268(struct hda_codec *codec)
        int board_config;
        int i, has_beep, err;
 
-       spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+       spec = kzalloc(sizeof(*spec), GFP_KERNEL);
        if (spec == NULL)
                return -ENOMEM;
 
index d057e64..5cfa608 100644 (file)
@@ -51,7 +51,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s
                        return 0; /* already enough large */
                vfree(runtime->dma_area);
        }
-       runtime->dma_area = vmalloc_32(size);
+       runtime->dma_area = vmalloc_32_user(size);
        if (! runtime->dma_area)
                return -ENOMEM;
        runtime->dma_bytes = size;
index b074a59..4963def 100644 (file)
@@ -752,7 +752,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t s
                        return 0; /* already large enough */
                vfree(runtime->dma_area);
        }
-       runtime->dma_area = vmalloc(size);
+       runtime->dma_area = vmalloc_user(size);
        if (!runtime->dma_area)
                return -ENOMEM;
        runtime->dma_bytes = size;