diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 1c8eb4518ce08e8a10303929692da407348a5c4c..fd9a2f67edf2a9e48b6c57758744855a7e278723 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -522,7 +522,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. pcm_devs - Number of PCM devices assigned to each card (default = 1, up to 4) pcm_substreams - Number of PCM substreams assigned to each PCM - (default = 8, up to 16) + (default = 8, up to 128) hrtimer - Use hrtimer (=1, default) or system timer (=0) fake_buffer - Fake buffer allocations (default = 1) diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 0c1440121c22c2f4ed8df37615c1241c17c5314e..c69c60b2a48ab9e55f1b90575c92541e0226e849 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -953,11 +953,12 @@ static int snd_pcm_dev_register(struct snd_device *device) struct snd_pcm_substream *substream; struct snd_pcm_notify *notify; char str[16]; - struct snd_pcm *pcm = device->device_data; + struct snd_pcm *pcm; struct device *dev; - if (snd_BUG_ON(!pcm || !device)) + if (snd_BUG_ON(!device || !device->device_data)) return -ENXIO; + pcm = device->device_data; mutex_lock(®ister_mutex); err = snd_pcm_add(pcm); if (err) { diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 6ba066c41d2e9bd5ab8d7c8e6f1eba438bda62af..252e04ce602f6adf6bf434f0b02edc24c4c8bb76 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c @@ -165,7 +165,7 @@ MODULE_PARM_DESC(enable, "Enable this dummy soundcard."); module_param_array(pcm_devs, int, NULL, 0444); MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver."); module_param_array(pcm_substreams, int, NULL, 0444); -MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-16) for dummy driver."); +MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver."); //module_param_array(midi_devs, int, NULL, 0444); //MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver."); module_param(fake_buffer, bool, 0444); @@ -808,8 +808,6 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy) unsigned int idx; int err; - if (snd_BUG_ON(!dummy)) - return -EINVAL; spin_lock_init(&dummy->mixer_lock); strcpy(card->mixername, "Dummy Mixer"); diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index 84cc2658c05b327e20a908d8fddb0f05f353fd12..e1145ac6e9086d15ee14179b4b53493bec21ad91 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -39,25 +39,20 @@ static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0); /* write the port and returns the next expire time in ns; * called at the trigger-start and in hrtimer callback */ -static unsigned long pcsp_timer_update(struct hrtimer *handle) +static u64 pcsp_timer_update(struct snd_pcsp *chip) { unsigned char timer_cnt, val; u64 ns; struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; - struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); unsigned long flags; if (chip->thalf) { outb(chip->val61, 0x61); chip->thalf = 0; - if (!atomic_read(&chip->timer_active)) - return 0; return chip->ns_rem; } - if (!atomic_read(&chip->timer_active)) - return 0; substream = chip->playback_substream; if (!substream) return 0; @@ -88,24 +83,17 @@ static unsigned long pcsp_timer_update(struct hrtimer *handle) return ns; } -enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) +static void pcsp_pointer_update(struct snd_pcsp *chip) { - struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); struct snd_pcm_substream *substream; - int periods_elapsed, pointer_update; size_t period_bytes, buffer_bytes; - unsigned long ns; + int periods_elapsed; unsigned long flags; - pointer_update = !chip->thalf; - ns = pcsp_timer_update(handle); - if (!ns) - return HRTIMER_NORESTART; - /* update the playback position */ substream = chip->playback_substream; if (!substream) - return HRTIMER_NORESTART; + return; period_bytes = snd_pcm_lib_period_bytes(substream); buffer_bytes = snd_pcm_lib_buffer_bytes(substream); @@ -134,6 +122,26 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) if (periods_elapsed) tasklet_schedule(&pcsp_pcm_tasklet); +} + +enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) +{ + struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); + int pointer_update; + u64 ns; + + if (!atomic_read(&chip->timer_active) || !chip->playback_substream) + return HRTIMER_NORESTART; + + pointer_update = !chip->thalf; + ns = pcsp_timer_update(chip); + if (!ns) { + printk(KERN_WARNING "PCSP: unexpected stop\n"); + return HRTIMER_NORESTART; + } + + if (pointer_update) + pcsp_pointer_update(chip); hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns)); @@ -142,8 +150,6 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) static int pcsp_start_playing(struct snd_pcsp *chip) { - unsigned long ns; - #if PCSP_DEBUG printk(KERN_INFO "PCSP: start_playing called\n"); #endif @@ -159,11 +165,7 @@ static int pcsp_start_playing(struct snd_pcsp *chip) atomic_set(&chip->timer_active, 1); chip->thalf = 0; - ns = pcsp_timer_update(&pcsp_chip.timer); - if (!ns) - return -EIO; - - hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL); + hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); return 0; } @@ -232,21 +234,22 @@ static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream) static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream) { struct snd_pcsp *chip = snd_pcm_substream_chip(substream); + pcsp_sync_stop(chip); + chip->playback_ptr = 0; + chip->period_ptr = 0; + chip->fmt_size = + snd_pcm_format_physical_width(substream->runtime->format) >> 3; + chip->is_signed = snd_pcm_format_signed(substream->runtime->format); #if PCSP_DEBUG printk(KERN_INFO "PCSP: prepare called, " - "size=%zi psize=%zi f=%zi f1=%i\n", + "size=%zi psize=%zi f=%zi f1=%i fsize=%i\n", snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream), snd_pcm_lib_buffer_bytes(substream) / snd_pcm_lib_period_bytes(substream), - substream->runtime->periods); + substream->runtime->periods, + chip->fmt_size); #endif - pcsp_sync_stop(chip); - chip->playback_ptr = 0; - chip->period_ptr = 0; - chip->fmt_size = - snd_pcm_format_physical_width(substream->runtime->format) >> 3; - chip->is_signed = snd_pcm_format_signed(substream->runtime->format); return 0; } diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c index 199b0337714279318c83c30070794ababc719329..903bc846763fa13da46e6c1f9aca6020953d661e 100644 --- a/sound/drivers/pcsp/pcsp_mixer.c +++ b/sound/drivers/pcsp/pcsp_mixer.c @@ -72,7 +72,7 @@ static int pcsp_treble_put(struct snd_kcontrol *kcontrol, if (treble != chip->treble) { chip->treble = treble; #if PCSP_DEBUG - printk(KERN_INFO "PCSP: rate set to %i\n", PCSP_RATE()); + printk(KERN_INFO "PCSP: rate set to %li\n", PCSP_RATE()); #endif changed = 1; } diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index e924492df21dc1b469f7b41020ca890737fa9857..f47f9e226b0823c35970fcbed96096e18042d15f 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c @@ -624,6 +624,9 @@ snd_harmony_pcm_init(struct snd_harmony *h) struct snd_pcm *pcm; int err; + if (snd_BUG_ON(!h)) + return -EINVAL; + harmony_disable_interrupts(h); err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm); @@ -865,11 +868,12 @@ snd_harmony_mixer_reset(struct snd_harmony *h) static int __devinit snd_harmony_mixer_init(struct snd_harmony *h) { - struct snd_card *card = h->card; + struct snd_card *card; int idx, err; if (snd_BUG_ON(!h)) return -EINVAL; + card = h->card; strcpy(card->mixername, "Harmony Gain control interface"); for (idx = 0; idx < HARMONY_CONTROLS; idx++) { diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index fb5ee3cc39682b2d412f9ce2059973f6570be9e5..75c602b5b1326c3430ff05b89661730dc377b44f 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -259,7 +259,6 @@ config SND_CS5530 config SND_CS5535AUDIO tristate "CS5535/CS5536 Audio" - depends on X86 && !X86_64 select SND_PCM select SND_AC97_CODEC help diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index b458d208720b1c6ac010ab235e122e3dd407f6e5..aaf4da68969c4572c9201e06f8ddc47cbd711f60 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -973,7 +973,7 @@ static void snd_ali_free_voice(struct snd_ali * codec, void *private_data; snd_ali_printk("free_voice: channel=%d\n",pvoice->number); - if (pvoice == NULL || !pvoice->use) + if (!pvoice->use) return; snd_ali_clear_voices(codec, pvoice->number, pvoice->number); spin_lock_irq(&codec->voice_alloc); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c9ad182e1b4b6a3ddd23b422f2e4f821bde90604..e340792f6cb325eabfca7c2e350aa987a9c35907 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2674,6 +2674,7 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x10de, 0x044b), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x055c), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x055d), .driver_data = AZX_DRIVER_NVIDIA }, + { PCI_DEVICE(0x10de, 0x0590), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0774), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0775), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0776), .driver_data = AZX_DRIVER_NVIDIA }, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c08ca660daba19a299173a0b9bcc1f442e11c22a..ff20048504b6484057e4a5464809c52773d7594e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -965,6 +965,8 @@ static void alc_automute_pin(struct hda_codec *codec) unsigned int nid = spec->autocfg.hp_pins[0]; int i; + if (!nid) + return; pincap = snd_hda_query_pin_caps(codec, nid); if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -12602,7 +12604,8 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", ALC268_ACER_ASPIRE_ONE), SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), - SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), + SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, + "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), /* almost compatible with toshiba but with optional digital outs; * auto-probing seems working fine */ @@ -17374,7 +17377,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, /* create playback/capture controls for input pins */ #define alc662_auto_create_input_ctls \ - alc880_auto_create_input_ctls + alc882_auto_create_input_ctls static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, int pin_type, diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 91683a34903543a3bded43fa140cf49b45294922..8a332d2f615cfc01e4612a9eb459628e8596c59b 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -386,6 +386,7 @@ struct via82xx { struct snd_pcm *pcms[2]; struct snd_rawmidi *rmidi; + struct snd_kcontrol *dxs_controls[4]; struct snd_ac97_bus *ac97_bus; struct snd_ac97 *ac97; @@ -1216,9 +1217,9 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev, /* - * open callback for playback on via686 and via823x DSX + * open callback for playback on via686 */ -static int snd_via82xx_playback_open(struct snd_pcm_substream *substream) +static int snd_via686_playback_open(struct snd_pcm_substream *substream) { struct via82xx *chip = snd_pcm_substream_chip(substream); struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number]; @@ -1229,6 +1230,32 @@ static int snd_via82xx_playback_open(struct snd_pcm_substream *substream) return 0; } +/* + * open callback for playback on via823x DXS + */ +static int snd_via8233_playback_open(struct snd_pcm_substream *substream) +{ + struct via82xx *chip = snd_pcm_substream_chip(substream); + struct viadev *viadev; + unsigned int stream; + int err; + + viadev = &chip->devs[chip->playback_devno + substream->number]; + if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0) + return err; + stream = viadev->reg_offset / 0x10; + if (chip->dxs_controls[stream]) { + chip->playback_volume[stream][0] = 0; + chip->playback_volume[stream][1] = 0; + chip->dxs_controls[stream]->vd[0].access &= + ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; + snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE | + SNDRV_CTL_EVENT_MASK_INFO, + &chip->dxs_controls[stream]->id); + } + return 0; +} + /* * open callback for playback on via823x multi-channel */ @@ -1302,10 +1329,26 @@ static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream) return 0; } +static int snd_via8233_playback_close(struct snd_pcm_substream *substream) +{ + struct via82xx *chip = snd_pcm_substream_chip(substream); + struct viadev *viadev = substream->runtime->private_data; + unsigned int stream; + + stream = viadev->reg_offset / 0x10; + if (chip->dxs_controls[stream]) { + chip->dxs_controls[stream]->vd[0].access |= + SNDRV_CTL_ELEM_ACCESS_INACTIVE; + snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_INFO, + &chip->dxs_controls[stream]->id); + } + return snd_via82xx_pcm_close(substream); +} + /* via686 playback callbacks */ static struct snd_pcm_ops snd_via686_playback_ops = { - .open = snd_via82xx_playback_open, + .open = snd_via686_playback_open, .close = snd_via82xx_pcm_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_via82xx_hw_params, @@ -1331,8 +1374,8 @@ static struct snd_pcm_ops snd_via686_capture_ops = { /* via823x DSX playback callbacks */ static struct snd_pcm_ops snd_via8233_playback_ops = { - .open = snd_via82xx_playback_open, - .close = snd_via82xx_pcm_close, + .open = snd_via8233_playback_open, + .close = snd_via8233_playback_close, .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_via82xx_hw_params, .hw_free = snd_via82xx_hw_free, @@ -1709,8 +1752,9 @@ static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = { .device = 0, /* .subdevice set later */ .name = "PCM Playback Volume", - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_INACTIVE, .info = snd_via8233_dxs_volume_info, .get = snd_via8233_dxs_volume_get, .put = snd_via8233_dxs_volume_put, @@ -1948,6 +1992,7 @@ static int __devinit snd_via8233_init_misc(struct via82xx *chip) err = snd_ctl_add(chip->card, kctl); if (err < 0) return err; + chip->dxs_controls[i] = kctl; } } } diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index 7dea74b71cf1ab8e1485a85b4e3f35b658a7b639..64b859925c0b16bd5ac458f25419fbcd8b4c3308 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -217,20 +217,25 @@ static void snd_pdacf_detach(struct pcmcia_device *link) * configuration callback */ -#define CS_CHECK(fn, ret) \ -do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) - static int pdacf_config(struct pcmcia_device *link) { struct snd_pdacf *pdacf = link->priv; - int last_fn, last_ret; + int ret; snd_printdd(KERN_DEBUG "pdacf_config called\n"); link->conf.ConfigIndex = 0x5; - CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + ret = pcmcia_request_io(link, &link->io); + if (ret) + goto failed; + + ret = pcmcia_request_irq(link, &link->irq); + if (ret) + goto failed; + + ret = pcmcia_request_configuration(link, &link->conf); + if (ret) + goto failed; if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) goto failed; @@ -238,8 +243,6 @@ static int pdacf_config(struct pcmcia_device *link) link->dev_node = &pdacf->node; return 0; -cs_failed: - cs_error(link, last_fn, last_ret); failed: pcmcia_disable_device(link); return -ENODEV; diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 7445cc8a47d380df120dadd3b813aa62baf0ff38..1492744ad67feb156ea03bf41182a21c25c98ca6 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -213,14 +213,11 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq * configuration callback */ -#define CS_CHECK(fn, ret) \ -do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) - static int vxpocket_config(struct pcmcia_device *link) { struct vx_core *chip = link->priv; struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; - int last_fn, last_ret; + int ret; snd_printdd(KERN_DEBUG "vxpocket_config called\n"); @@ -235,9 +232,17 @@ static int vxpocket_config(struct pcmcia_device *link) strcpy(chip->card->driver, vxp440_hw.name); } - CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); - CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); - CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); + ret = pcmcia_request_io(link, &link->io); + if (ret) + goto failed; + + ret = pcmcia_request_irq(link, &link->irq); + if (ret) + goto failed; + + ret = pcmcia_request_configuration(link, &link->conf); + if (ret) + goto failed; chip->dev = &handle_to_dev(link); snd_card_set_dev(chip->card, chip->dev); @@ -248,8 +253,6 @@ static int vxpocket_config(struct pcmcia_device *link) link->dev_node = &vxp->node; return 0; -cs_failed: - cs_error(link, last_fn, last_ret); failed: pcmcia_disable_device(link); return -ENODEV; diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index 2dee9839be86035f6b668655dcf84aa12d9e843c..653a362425dfd265b70068361495c0404908df60 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -21,7 +21,18 @@ config SND_OMAP_SOC_AMS_DELTA select SND_OMAP_SOC_MCBSP select SND_SOC_CX20442 help - Say Y if you want to add support for SoC audio on Amstrad Delta. + Say Y if you want to add support for SoC audio device connected to + a handset and a speakerphone found on Amstrad E3 (Delta) videophone. + + Note that in order to get those devices fully supported, you have to + build the kernel with standard serial port driver included and + configured for at least 4 ports. Then, from userspace, you must load + a line discipline #19 on the modem (ttyS3) serial line. The simplest + way to achieve this is to install util-linux-ng and use the included + ldattach utility. This can be started automatically from udev, + a simple rule like this one should do the trick (it does for me): + ACTION=="add", KERNEL=="controlC0", \ + RUN+="/usr/sbin/ldattach 19 /dev/ttyS3" config SND_OMAP_SOC_OSK5912 tristate "SoC Audio support for omap osk5912" diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 7ff04ad2a97e0511d7b31d49cb7b481c9c0214ed..0a1b2f64bbee38a18947a9fa161eb922dc0f17a0 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -834,6 +834,9 @@ EXPORT_SYMBOL_GPL(snd_soc_resume_device); #define soc_resume NULL #endif +static struct snd_soc_dai_ops null_dai_ops = { +}; + static void snd_soc_instantiate_card(struct snd_soc_card *card) { struct platform_device *pdev = container_of(card->dev, @@ -877,6 +880,11 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) ac97 = 1; } + for (i = 0; i < card->num_links; i++) { + if (!card->dai_link[i].codec_dai->ops) + card->dai_link[i].codec_dai->ops = &null_dai_ops; + } + /* If we have AC97 in the system then don't wait for the * codec. This will need revisiting if we have to handle * systems with mixed AC97 and non-AC97 parts. Only check for @@ -2329,9 +2337,6 @@ static int snd_soc_unregister_card(struct snd_soc_card *card) return 0; } -static struct snd_soc_dai_ops null_dai_ops = { -}; - /** * snd_soc_register_dai - Register a DAI with the ASoC core * diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 8de6f9dec4a225a495825c86f2dcf03e167403fb..d89f6dc00908284d0e97e5778dfe9444b99683ff 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2072,9 +2072,9 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, } } } - mutex_unlock(&codec->mutex); dapm_power_widgets(codec, event); + mutex_unlock(&codec->mutex); dump_dapm(codec, __func__); return 0; } diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 121af0644fd9bc901fbbc62cb676738e9049e0c7..86b2c3b92df53abafa8188560c4e034ce987ea97 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c @@ -62,10 +62,14 @@ static void activate_substream(struct snd_usb_caiaqdev *dev, struct snd_pcm_substream *sub) { + spin_lock(&dev->spinlock); + if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) dev->sub_playback[sub->number] = sub; else dev->sub_capture[sub->number] = sub; + + spin_unlock(&dev->spinlock); } static void @@ -269,16 +273,22 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) { int index = sub->number; struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub); + snd_pcm_uframes_t ptr; + + spin_lock(&dev->spinlock); if (dev->input_panic || dev->output_panic) - return SNDRV_PCM_POS_XRUN; + ptr = SNDRV_PCM_POS_XRUN; if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) - return bytes_to_frames(sub->runtime, + ptr = bytes_to_frames(sub->runtime, dev->audio_out_buf_pos[index]); else - return bytes_to_frames(sub->runtime, + ptr = bytes_to_frames(sub->runtime, dev->audio_in_buf_pos[index]); + + spin_unlock(&dev->spinlock); + return ptr; } /* operators for both playback and capture */ diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 83e6c1312d47c47ef1cc32eabab5b411d9dfa6b3..a3f02dd974406bb60b2f10f9d7bd4108b80b589e 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c @@ -35,7 +35,7 @@ #include "input.h" MODULE_AUTHOR("Daniel Mack "); -MODULE_DESCRIPTION("caiaq USB audio, version 1.3.19"); +MODULE_DESCRIPTION("caiaq USB audio, version 1.3.20"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," "{Native Instruments, RigKontrol3},"