Commit 3de62951 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-fix-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Just a collection of small fixes here: the most outstanding one is the
  re-application of USB-audio lowlatency support that was reverted in
  the previous PR. The rest are device-specific quirks/fixes, spelling
  fixes and a regression fix for the old intel8x0 driver"

* tag 'sound-fix-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: intel8x0: Fix breakage at ac97 clock measurement
  ALSA: usb-audio: Reduce latency at playback start, take#2
  ALSA: isa: Fix error return code in snd_cmi8330_probe()
  ALSA: emux: fix spelling mistakes
  ALSA: usb-audio: fix spelling mistakes
  ALSA: bebob: correct duplicated entries with TerraTec OUI
  ALSA: usx2y: fix spelling mistakes
  ALSA: x86: fix spelling mistakes
  ALSA: hda/realtek: fix mute led of the HP Pavilion 15-eh1xxx series
parents 5a7f7fc5 24d1e494
...@@ -403,8 +403,6 @@ static const struct ieee1394_device_id bebob_id_table[] = { ...@@ -403,8 +403,6 @@ static const struct ieee1394_device_id bebob_id_table[] = {
SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x01eeee, &spec_normal), SND_BEBOB_DEV_ENTRY(VEN_APOGEE, 0x01eeee, &spec_normal),
/* ESI, Quatafire610 */ /* ESI, Quatafire610 */
SND_BEBOB_DEV_ENTRY(VEN_ESI, 0x00010064, &spec_normal), SND_BEBOB_DEV_ENTRY(VEN_ESI, 0x00010064, &spec_normal),
// AcousticReality, eARMasterOne. Terratec OEM.
SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal),
/* CME, MatrixKFW */ /* CME, MatrixKFW */
SND_BEBOB_DEV_ENTRY(VEN_CME, 0x00030000, &spec_normal), SND_BEBOB_DEV_ENTRY(VEN_CME, 0x00030000, &spec_normal),
// Phonic Helix Board 12 FireWire MkII. // Phonic Helix Board 12 FireWire MkII.
...@@ -434,7 +432,8 @@ static const struct ieee1394_device_id bebob_id_table[] = { ...@@ -434,7 +432,8 @@ static const struct ieee1394_device_id bebob_id_table[] = {
SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &yamaha_terratec_spec), SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000007, &yamaha_terratec_spec),
/* TerraTec Electronic GmbH, EWS MIC2/MIC8 */ /* TerraTec Electronic GmbH, EWS MIC2/MIC8 */
SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal), SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000005, &spec_normal),
/* Terratec Electronic GmbH, Aureon 7.1 Firewire */ // Terratec Electronic GmbH, Aureon 7.1 Firewire.
// AcousticReality, eAR Master One, Eroica, Figaro, and Ciaccona. Perhaps Terratec OEM.
SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal), SND_BEBOB_DEV_ENTRY(VEN_TERRATEC, 0x00000002, &spec_normal),
/* Yamaha, GO44 */ /* Yamaha, GO44 */
SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_terratec_spec), SND_BEBOB_DEV_ENTRY(VEN_YAMAHA, 0x0010000b, &yamaha_terratec_spec),
......
...@@ -551,7 +551,7 @@ static int snd_cmi8330_probe(struct snd_card *card, int dev) ...@@ -551,7 +551,7 @@ static int snd_cmi8330_probe(struct snd_card *card, int dev)
} }
if (acard->sb->hardware != SB_HW_16) { if (acard->sb->hardware != SB_HW_16) {
snd_printk(KERN_ERR PFX "SB16 not found during probe\n"); snd_printk(KERN_ERR PFX "SB16 not found during probe\n");
return err; return -ENODEV;
} }
snd_wss_out(acard->wss, CS4231_MISC_INFO, 0x40); /* switch on MODE2 */ snd_wss_out(acard->wss, CS4231_MISC_INFO, 0x40); /* switch on MODE2 */
......
...@@ -8442,6 +8442,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -8442,6 +8442,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
......
...@@ -694,7 +694,7 @@ static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ich ...@@ -694,7 +694,7 @@ static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ich
int status, civ, i, step; int status, civ, i, step;
int ack = 0; int ack = 0;
if (!ichdev->prepared || ichdev->suspended) if (!(ichdev->prepared || chip->in_measurement) || ichdev->suspended)
return; return;
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
......
...@@ -69,7 +69,7 @@ static const int gs_sense[] = ...@@ -69,7 +69,7 @@ static const int gs_sense[] =
DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
}; };
/* effect sensitivies for XG controls: /* effect sensitivities for XG controls:
* adjusted for chaos 8MB soundfonts * adjusted for chaos 8MB soundfonts
*/ */
static const int xg_sense[] = static const int xg_sense[] =
......
...@@ -108,7 +108,7 @@ snd_soundfont_close_check(struct snd_sf_list *sflist, int client) ...@@ -108,7 +108,7 @@ snd_soundfont_close_check(struct snd_sf_list *sflist, int client)
* Deal with a soundfont patch. Any driver could use these routines * Deal with a soundfont patch. Any driver could use these routines
* although it was designed for the AWE64. * although it was designed for the AWE64.
* *
* The sample_write and callargs pararameters allow a callback into * The sample_write and callargs parameters allow a callback into
* the actual driver to write sample data to the board or whatever * the actual driver to write sample data to the board or whatever
* it wants to do with it. * it wants to do with it.
*/ */
...@@ -799,7 +799,7 @@ snd_sf_linear_to_log(unsigned int amount, int offset, int ratio) ...@@ -799,7 +799,7 @@ snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
amount <<= 1; amount <<= 1;
s = (amount >> 24) & 0x7f; s = (amount >> 24) & 0x7f;
low = (amount >> 16) & 0xff; low = (amount >> 16) & 0xff;
/* linear approxmimation by lower 8 bit */ /* linear approximation by lower 8 bit */
v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8; v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8;
v -= offset; v -= offset;
v = (v * ratio) >> 16; v = (v * ratio) >> 16;
...@@ -1433,7 +1433,7 @@ snd_sf_free(struct snd_sf_list *sflist) ...@@ -1433,7 +1433,7 @@ snd_sf_free(struct snd_sf_list *sflist)
/* /*
* Remove all samples * Remove all samples
* The soundcard should be silet before calling this function. * The soundcard should be silent before calling this function.
*/ */
int int
snd_soundfont_remove_samples(struct snd_sf_list *sflist) snd_soundfont_remove_samples(struct snd_sf_list *sflist)
......
...@@ -19,7 +19,7 @@ struct audioformat { ...@@ -19,7 +19,7 @@ struct audioformat {
unsigned char iface; /* interface number */ unsigned char iface; /* interface number */
unsigned char altsetting; /* corresponding alternate setting */ unsigned char altsetting; /* corresponding alternate setting */
unsigned char ep_idx; /* endpoint array index */ unsigned char ep_idx; /* endpoint array index */
unsigned char altset_idx; /* array index of altenate setting */ unsigned char altset_idx; /* array index of alternate setting */
unsigned char attributes; /* corresponding attributes of cs endpoint */ unsigned char attributes; /* corresponding attributes of cs endpoint */
unsigned char endpoint; /* endpoint */ unsigned char endpoint; /* endpoint */
unsigned char ep_attr; /* endpoint attributes */ unsigned char ep_attr; /* endpoint attributes */
...@@ -158,6 +158,7 @@ struct snd_usb_substream { ...@@ -158,6 +158,7 @@ struct snd_usb_substream {
unsigned int stream_offset_adj; /* Bytes to drop from beginning of stream (for non-compliant devices) */ unsigned int stream_offset_adj; /* Bytes to drop from beginning of stream (for non-compliant devices) */
unsigned int running: 1; /* running status */ unsigned int running: 1; /* running status */
unsigned int period_elapsed_pending; /* delay period handling */
unsigned int buffer_bytes; /* buffer size in bytes */ unsigned int buffer_bytes; /* buffer size in bytes */
unsigned int inflight_bytes; /* in-flight data bytes on buffer (for playback) */ unsigned int inflight_bytes; /* in-flight data bytes on buffer (for playback) */
......
...@@ -645,7 +645,7 @@ static bool endpoint_compatible(struct snd_usb_endpoint *ep, ...@@ -645,7 +645,7 @@ static bool endpoint_compatible(struct snd_usb_endpoint *ep,
} }
/* /*
* Check whether the given fp and hw params are compatbile with the current * Check whether the given fp and hw params are compatible with the current
* setup of the target EP for implicit feedback sync * setup of the target EP for implicit feedback sync
*/ */
bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip, bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip,
...@@ -1245,7 +1245,7 @@ static int snd_usb_endpoint_set_params(struct snd_usb_audio *chip, ...@@ -1245,7 +1245,7 @@ static int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
* *
* This function sets up the EP to be fully usable state. * This function sets up the EP to be fully usable state.
* It's called either from hw_params or prepare callback. * It's called either from hw_params or prepare callback.
* The function checks need_setup flag, and perfoms nothing unless needed, * The function checks need_setup flag, and performs nothing unless needed,
* so it's safe to call this multiple times. * so it's safe to call this multiple times.
* *
* This returns zero if unchanged, 1 if the configuration has changed, * This returns zero if unchanged, 1 if the configuration has changed,
......
...@@ -285,7 +285,7 @@ int snd_media_device_create(struct snd_usb_audio *chip, ...@@ -285,7 +285,7 @@ int snd_media_device_create(struct snd_usb_audio *chip,
ret); ret);
if (!media_devnode_is_registered(mdev->devnode)) { if (!media_devnode_is_registered(mdev->devnode)) {
/* dont'register if snd_media_mixer_init() failed */ /* don't register if snd_media_mixer_init() failed */
if (ret) if (ret)
goto create_fail; goto create_fail;
......
...@@ -163,7 +163,7 @@ snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 a, ...@@ -163,7 +163,7 @@ snd_s1810c_send_ctl_packet(struct usb_device *dev, u32 a,
} }
/* /*
* When opening Universal Control the program periodicaly * When opening Universal Control the program periodically
* sends and receives state packets for syncinc state between * sends and receives state packets for syncinc state between
* the device and the host. * the device and the host.
* *
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* Auto-detection via UAC2 is not feasible to properly discover the vast * Auto-detection via UAC2 is not feasible to properly discover the vast
* majority of features. It's related to both Linux/ALSA's UAC2 as well as * majority of features. It's related to both Linux/ALSA's UAC2 as well as
* Focusrite's implementation of it. Eventually quirks may be sufficient but * Focusrite's implementation of it. Eventually quirks may be sufficient but
* right now it's a major headache to work arount these things. * right now it's a major headache to work around these things.
* *
* NB. Neither the OSX nor the win driver provided by Focusrite performs * NB. Neither the OSX nor the win driver provided by Focusrite performs
* discovery, they seem to operate the same as this driver. * discovery, they seem to operate the same as this driver.
......
...@@ -611,13 +611,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -611,13 +611,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
subs->hwptr_done = 0; subs->hwptr_done = 0;
subs->transfer_done = 0; subs->transfer_done = 0;
subs->last_frame_number = 0; subs->last_frame_number = 0;
subs->period_elapsed_pending = 0;
runtime->delay = 0; runtime->delay = 0;
/* for playback, submit the URBs now; otherwise, the first hwptr_done
* updates for all URBs would happen at the same time when starting */
if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
ret = start_endpoints(subs);
unlock: unlock:
snd_usb_unlock_shutdown(chip); snd_usb_unlock_shutdown(chip);
return ret; return ret;
...@@ -1398,6 +1394,10 @@ static void prepare_playback_urb(struct snd_usb_substream *subs, ...@@ -1398,6 +1394,10 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
subs->trigger_tstamp_pending_update = false; subs->trigger_tstamp_pending_update = false;
} }
if (period_elapsed && !subs->running) {
subs->period_elapsed_pending = 1;
period_elapsed = 0;
}
spin_unlock_irqrestore(&subs->lock, flags); spin_unlock_irqrestore(&subs->lock, flags);
urb->transfer_buffer_length = bytes; urb->transfer_buffer_length = bytes;
if (period_elapsed) if (period_elapsed)
...@@ -1413,6 +1413,7 @@ static void retire_playback_urb(struct snd_usb_substream *subs, ...@@ -1413,6 +1413,7 @@ static void retire_playback_urb(struct snd_usb_substream *subs,
{ {
unsigned long flags; unsigned long flags;
struct snd_urb_ctx *ctx = urb->context; struct snd_urb_ctx *ctx = urb->context;
bool period_elapsed = false;
spin_lock_irqsave(&subs->lock, flags); spin_lock_irqsave(&subs->lock, flags);
if (ctx->queued) { if (ctx->queued) {
...@@ -1423,13 +1424,20 @@ static void retire_playback_urb(struct snd_usb_substream *subs, ...@@ -1423,13 +1424,20 @@ static void retire_playback_urb(struct snd_usb_substream *subs,
} }
subs->last_frame_number = usb_get_current_frame_number(subs->dev); subs->last_frame_number = usb_get_current_frame_number(subs->dev);
if (subs->running) {
period_elapsed = subs->period_elapsed_pending;
subs->period_elapsed_pending = 0;
}
spin_unlock_irqrestore(&subs->lock, flags); spin_unlock_irqrestore(&subs->lock, flags);
if (period_elapsed)
snd_pcm_period_elapsed(subs->pcm_substream);
} }
static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream,
int cmd) int cmd)
{ {
struct snd_usb_substream *subs = substream->runtime->private_data; struct snd_usb_substream *subs = substream->runtime->private_data;
int err;
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
...@@ -1440,6 +1448,14 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea ...@@ -1440,6 +1448,14 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea
prepare_playback_urb, prepare_playback_urb,
retire_playback_urb, retire_playback_urb,
subs); subs);
if (cmd == SNDRV_PCM_TRIGGER_START) {
err = start_endpoints(subs);
if (err < 0) {
snd_usb_endpoint_set_callback(subs->data_endpoint,
NULL, NULL, NULL);
return err;
}
}
subs->running = 1; subs->running = 1;
dev_dbg(&subs->dev->dev, "%d:%d Start Playback PCM\n", dev_dbg(&subs->dev->dev, "%d:%d Start Playback PCM\n",
subs->cur_audiofmt->iface, subs->cur_audiofmt->iface,
......
...@@ -526,7 +526,7 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs) ...@@ -526,7 +526,7 @@ static int usx2y_urbs_start(struct snd_usx2y_substream *subs)
cleanup: cleanup:
if (err) { if (err) {
usx2y_subs_startup_finish(usx2y); usx2y_subs_startup_finish(usx2y);
usx2y_clients_stop(usx2y); // something is completely wroong > stop evrything usx2y_clients_stop(usx2y); // something is completely wrong > stop everything
} }
return err; return err;
} }
......
...@@ -480,7 +480,7 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs) ...@@ -480,7 +480,7 @@ static int usx2y_usbpcm_urbs_start(struct snd_usx2y_substream *subs)
cleanup: cleanup:
if (err) { if (err) {
usx2y_subs_startup_finish(usx2y); // Call it now usx2y_subs_startup_finish(usx2y); // Call it now
usx2y_clients_stop(usx2y); // something is completely wroong > stop evrything usx2y_clients_stop(usx2y); // something is completely wrong > stop everything
} }
return err; return err;
} }
......
...@@ -236,7 +236,7 @@ static void had_write_register(struct snd_intelhad *ctx, u32 reg, u32 val) ...@@ -236,7 +236,7 @@ static void had_write_register(struct snd_intelhad *ctx, u32 reg, u32 val)
* updating AUD_CONFIG register. * updating AUD_CONFIG register.
* This is because: * This is because:
* Bit6 of AUD_CONFIG register is writeonly due to a silicon bug on VLV2 * Bit6 of AUD_CONFIG register is writeonly due to a silicon bug on VLV2
* HDMI IP. As a result a read-modify of AUD_CONFIG regiter will always * HDMI IP. As a result a read-modify of AUD_CONFIG register will always
* clear bit6. AUD_CONFIG[6:4] represents the "channels" field of the * clear bit6. AUD_CONFIG[6:4] represents the "channels" field of the
* register. This field should be 1xy binary for configuration with 6 or * register. This field should be 1xy binary for configuration with 6 or
* more channels. Read-modify of AUD_CONFIG (Eg. for enabling audio) * more channels. Read-modify of AUD_CONFIG (Eg. for enabling audio)
...@@ -342,7 +342,7 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, ...@@ -342,7 +342,7 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream,
/* /*
* function to initialize audio * function to initialize audio
* registers and buffer confgiuration registers * registers and buffer configuration registers
* This function is called in the prepare callback * This function is called in the prepare callback
*/ */
static int had_init_audio_ctrl(struct snd_pcm_substream *substream, static int had_init_audio_ctrl(struct snd_pcm_substream *substream,
...@@ -1790,7 +1790,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) ...@@ -1790,7 +1790,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
pcm->private_data = ctx; pcm->private_data = ctx;
pcm->info_flags = 0; pcm->info_flags = 0;
strscpy(pcm->name, card->shortname, strlen(card->shortname)); strscpy(pcm->name, card->shortname, strlen(card->shortname));
/* setup the ops for playabck */ /* setup the ops for playback */
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &had_pcm_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &had_pcm_ops);
/* allocate dma pages; /* allocate dma pages;
......
...@@ -96,7 +96,7 @@ struct pcm_stream_info { ...@@ -96,7 +96,7 @@ struct pcm_stream_info {
* @had_spinlock: driver lock * @had_spinlock: driver lock
* @aes_bits: IEC958 status bits * @aes_bits: IEC958 status bits
* @buff_done: id of current buffer done intr * @buff_done: id of current buffer done intr
* @dev: platoform device handle * @dev: platform device handle
* @chmap: holds channel map info * @chmap: holds channel map info
*/ */
struct snd_intelhad { struct snd_intelhad {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment