Commit 4aafdf68 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull sound fixes from Takashi Iwai:
 "A collection of small fixes gathered since the previous update.

  ALSA core:
   - Regression fix for OSS PCM emulation

  ASoC:
   - Trivial fixes in reg bit mask ops, DAPM, DPCM and topology
   - Lots of fixes for Intel-based devices
   - Minor fixes for AMD, STM32, Qualcomm, Realtek

  Others:
   - Fixes for the bugs in mixer handling in HD-audio and ice1724
     drivers that were caught by the recent kctl validator
   - New quirks for HD-audio and USB-audio

  Also this contains a fix for EDD firmware fix, which slipped from
  anyone's hands"

* tag 'sound-fix-5.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (35 commits)
  ALSA: hda: Add driver blacklist
  ALSA: usb-audio: Add mixer workaround for TRX40 and co
  ALSA: hda/realtek - Add quirk for MSI GL63
  ALSA: ice1724: Fix invalid access for enumerated ctl items
  ALSA: hda: Fix potential access overflow in beep helper
  ASoC: cs4270: pull reset GPIO low then high
  ALSA: hda/realtek - Add HP new mute led supported for ALC236
  ALSA: hda/realtek - Add supported new mute Led for HP
  ASoC: rt5645: Add platform-data for Medion E1239T
  ASoC: Intel: bytcr_rt5640: Add quirk for MPMAN MPWIN895CL tablet
  ASoC: stm32: sai: Add missing cleanup
  ALSA: usb-audio: Add registration quirk for Kingston HyperX Cloud Alpha S
  ASoC: Intel: atom: Fix uninitialized variable compiler warning
  ASoC: Intel: atom: Check drv->lock is locked in sst_fill_and_send_cmd_unlocked
  ASoC: Intel: atom: Take the drv->lock mutex before calling sst_send_slot_map()
  ASoC: SOF: Turn "firmware boot complete" message into a dbg message
  ALSA: usb-audio: Add Pioneer DJ DJM-250MK2 quirk
  ALSA: pcm: oss: Fix regression by buffer overflow fix (again)
  ALSA: pcm: oss: Fix regression by buffer overflow fix
  edd: Use scnprintf() for avoiding potential buffer overflow
  ...
parents 93f3321f ddd5609f
...@@ -49,7 +49,7 @@ required: ...@@ -49,7 +49,7 @@ required:
examples: examples:
- | - |
#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/gpio/gpio.h>
i2c@0 { i2c {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
......
...@@ -341,7 +341,7 @@ edd_show_legacy_max_cylinder(struct edd_device *edev, char *buf) ...@@ -341,7 +341,7 @@ edd_show_legacy_max_cylinder(struct edd_device *edev, char *buf)
if (!info || !buf) if (!info || !buf)
return -EINVAL; return -EINVAL;
p += snprintf(p, left, "%u\n", info->legacy_max_cylinder); p += scnprintf(p, left, "%u\n", info->legacy_max_cylinder);
return (p - buf); return (p - buf);
} }
...@@ -356,7 +356,7 @@ edd_show_legacy_max_head(struct edd_device *edev, char *buf) ...@@ -356,7 +356,7 @@ edd_show_legacy_max_head(struct edd_device *edev, char *buf)
if (!info || !buf) if (!info || !buf)
return -EINVAL; return -EINVAL;
p += snprintf(p, left, "%u\n", info->legacy_max_head); p += scnprintf(p, left, "%u\n", info->legacy_max_head);
return (p - buf); return (p - buf);
} }
...@@ -371,7 +371,7 @@ edd_show_legacy_sectors_per_track(struct edd_device *edev, char *buf) ...@@ -371,7 +371,7 @@ edd_show_legacy_sectors_per_track(struct edd_device *edev, char *buf)
if (!info || !buf) if (!info || !buf)
return -EINVAL; return -EINVAL;
p += snprintf(p, left, "%u\n", info->legacy_sectors_per_track); p += scnprintf(p, left, "%u\n", info->legacy_sectors_per_track);
return (p - buf); return (p - buf);
} }
......
...@@ -351,7 +351,7 @@ struct snd_soc_dai { ...@@ -351,7 +351,7 @@ struct snd_soc_dai {
/* bit field */ /* bit field */
unsigned int probed:1; unsigned int probed:1;
unsigned int started:1; unsigned int started[SNDRV_PCM_STREAM_LAST + 1];
}; };
static inline struct snd_soc_pcm_stream * static inline struct snd_soc_pcm_stream *
......
...@@ -197,7 +197,8 @@ int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin) ...@@ -197,7 +197,8 @@ int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin)
} }
static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug, static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug,
snd_pcm_sframes_t frames) snd_pcm_sframes_t frames,
bool check_size)
{ {
struct snd_pcm_plugin *plugin, *plugin_next; struct snd_pcm_plugin *plugin, *plugin_next;
...@@ -209,7 +210,7 @@ static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug, ...@@ -209,7 +210,7 @@ static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug,
if (frames < 0) if (frames < 0)
return frames; return frames;
} }
if (frames > plugin->buf_frames) if (check_size && frames > plugin->buf_frames)
frames = plugin->buf_frames; frames = plugin->buf_frames;
plugin = plugin_next; plugin = plugin_next;
} }
...@@ -217,13 +218,14 @@ static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug, ...@@ -217,13 +218,14 @@ static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug,
} }
static snd_pcm_sframes_t calc_src_frames(struct snd_pcm_substream *plug, static snd_pcm_sframes_t calc_src_frames(struct snd_pcm_substream *plug,
snd_pcm_sframes_t frames) snd_pcm_sframes_t frames,
bool check_size)
{ {
struct snd_pcm_plugin *plugin, *plugin_prev; struct snd_pcm_plugin *plugin, *plugin_prev;
plugin = snd_pcm_plug_last(plug); plugin = snd_pcm_plug_last(plug);
while (plugin && frames > 0) { while (plugin && frames > 0) {
if (frames > plugin->buf_frames) if (check_size && frames > plugin->buf_frames)
frames = plugin->buf_frames; frames = plugin->buf_frames;
plugin_prev = plugin->prev; plugin_prev = plugin->prev;
if (plugin->src_frames) { if (plugin->src_frames) {
...@@ -242,9 +244,9 @@ snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_p ...@@ -242,9 +244,9 @@ snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_p
return -ENXIO; return -ENXIO;
switch (snd_pcm_plug_stream(plug)) { switch (snd_pcm_plug_stream(plug)) {
case SNDRV_PCM_STREAM_PLAYBACK: case SNDRV_PCM_STREAM_PLAYBACK:
return calc_src_frames(plug, drv_frames); return calc_src_frames(plug, drv_frames, false);
case SNDRV_PCM_STREAM_CAPTURE: case SNDRV_PCM_STREAM_CAPTURE:
return calc_dst_frames(plug, drv_frames); return calc_dst_frames(plug, drv_frames, false);
default: default:
snd_BUG(); snd_BUG();
return -EINVAL; return -EINVAL;
...@@ -257,9 +259,9 @@ snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pc ...@@ -257,9 +259,9 @@ snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pc
return -ENXIO; return -ENXIO;
switch (snd_pcm_plug_stream(plug)) { switch (snd_pcm_plug_stream(plug)) {
case SNDRV_PCM_STREAM_PLAYBACK: case SNDRV_PCM_STREAM_PLAYBACK:
return calc_dst_frames(plug, clt_frames); return calc_dst_frames(plug, clt_frames, false);
case SNDRV_PCM_STREAM_CAPTURE: case SNDRV_PCM_STREAM_CAPTURE:
return calc_src_frames(plug, clt_frames); return calc_src_frames(plug, clt_frames, false);
default: default:
snd_BUG(); snd_BUG();
return -EINVAL; return -EINVAL;
...@@ -622,7 +624,7 @@ snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, st ...@@ -622,7 +624,7 @@ snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, st
src_channels = dst_channels; src_channels = dst_channels;
plugin = next; plugin = next;
} }
return snd_pcm_plug_client_size(plug, frames); return calc_src_frames(plug, frames, true);
} }
snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *dst_channels_final, snd_pcm_uframes_t size) snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *dst_channels_final, snd_pcm_uframes_t size)
...@@ -632,7 +634,7 @@ snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, str ...@@ -632,7 +634,7 @@ snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, str
snd_pcm_sframes_t frames = size; snd_pcm_sframes_t frames = size;
int err; int err;
frames = snd_pcm_plug_slave_size(plug, frames); frames = calc_src_frames(plug, frames, true);
if (frames < 0) if (frames < 0)
return frames; return frames;
......
...@@ -290,8 +290,12 @@ int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, ...@@ -290,8 +290,12 @@ int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
{ {
struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct hda_beep *beep = codec->beep; struct hda_beep *beep = codec->beep;
int chs = get_amp_channels(kcontrol);
if (beep && (!beep->enabled || !ctl_has_mute(kcontrol))) { if (beep && (!beep->enabled || !ctl_has_mute(kcontrol))) {
ucontrol->value.integer.value[0] = if (chs & 1)
ucontrol->value.integer.value[0] = beep->enabled;
if (chs & 2)
ucontrol->value.integer.value[1] = beep->enabled; ucontrol->value.integer.value[1] = beep->enabled;
return 0; return 0;
} }
......
...@@ -2076,6 +2076,17 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream, ...@@ -2076,6 +2076,17 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream,
#endif #endif
} }
/* Blacklist for skipping the whole probe:
* some HD-audio PCI entries are exposed without any codecs, and such devices
* should be ignored from the beginning.
*/
static const struct snd_pci_quirk driver_blacklist[] = {
SND_PCI_QUIRK(0x1043, 0x874f, "ASUS ROG Zenith II / Strix", 0),
SND_PCI_QUIRK(0x1462, 0xcb59, "MSI TRX40 Creator", 0),
SND_PCI_QUIRK(0x1462, 0xcb60, "MSI TRX40", 0),
{}
};
static const struct hda_controller_ops pci_hda_ops = { static const struct hda_controller_ops pci_hda_ops = {
.disable_msi_reset_irq = disable_msi_reset_irq, .disable_msi_reset_irq = disable_msi_reset_irq,
.pcm_mmap_prepare = pcm_mmap_prepare, .pcm_mmap_prepare = pcm_mmap_prepare,
...@@ -2092,6 +2103,11 @@ static int azx_probe(struct pci_dev *pci, ...@@ -2092,6 +2103,11 @@ static int azx_probe(struct pci_dev *pci,
bool schedule_probe; bool schedule_probe;
int err; int err;
if (snd_pci_quirk_lookup(pci, driver_blacklist)) {
dev_info(&pci->dev, "Skipping the blacklisted device\n");
return -ENODEV;
}
if (dev >= SNDRV_CARDS) if (dev >= SNDRV_CARDS)
return -ENODEV; return -ENODEV;
if (!enable[dev]) { if (!enable[dev]) {
......
...@@ -86,6 +86,14 @@ struct alc_spec { ...@@ -86,6 +86,14 @@ struct alc_spec {
unsigned int gpio_mute_led_mask; unsigned int gpio_mute_led_mask;
unsigned int gpio_mic_led_mask; unsigned int gpio_mic_led_mask;
unsigned int mute_led_coef_idx;
unsigned int mute_led_coefbit_mask;
unsigned int mute_led_coefbit_on;
unsigned int mute_led_coefbit_off;
unsigned int mic_led_coef_idx;
unsigned int mic_led_coefbit_mask;
unsigned int mic_led_coefbit_on;
unsigned int mic_led_coefbit_off;
hda_nid_t headset_mic_pin; hda_nid_t headset_mic_pin;
hda_nid_t headphone_mic_pin; hda_nid_t headphone_mic_pin;
...@@ -2447,6 +2455,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { ...@@ -2447,6 +2455,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS), SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x1275, "MSI-GL63", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
...@@ -4178,6 +4187,111 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, ...@@ -4178,6 +4187,111 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
} }
} }
/* update mute-LED according to the speaker mute state via COEF bit */
static void alc_fixup_mute_led_coefbit_hook(void *private_data, int enabled)
{
struct hda_codec *codec = private_data;
struct alc_spec *spec = codec->spec;
if (spec->mute_led_polarity)
enabled = !enabled;
/* temporarily power up/down for setting COEF bit */
enabled ? alc_update_coef_idx(codec, spec->mute_led_coef_idx,
spec->mute_led_coefbit_mask, spec->mute_led_coefbit_off) :
alc_update_coef_idx(codec, spec->mute_led_coef_idx,
spec->mute_led_coefbit_mask, spec->mute_led_coefbit_on);
}
static void alc285_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
const struct hda_fixup *fix,
int action)
{
struct alc_spec *spec = codec->spec;
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->mute_led_polarity = 0;
spec->mute_led_coef_idx = 0x0b;
spec->mute_led_coefbit_mask = 1<<3;
spec->mute_led_coefbit_on = 1<<3;
spec->mute_led_coefbit_off = 0;
spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook;
spec->gen.vmaster_mute_enum = 1;
}
}
static void alc236_fixup_hp_mute_led_coefbit(struct hda_codec *codec,
const struct hda_fixup *fix,
int action)
{
struct alc_spec *spec = codec->spec;
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->mute_led_polarity = 0;
spec->mute_led_coef_idx = 0x34;
spec->mute_led_coefbit_mask = 1<<5;
spec->mute_led_coefbit_on = 0;
spec->mute_led_coefbit_off = 1<<5;
spec->gen.vmaster_mute.hook = alc_fixup_mute_led_coefbit_hook;
spec->gen.vmaster_mute_enum = 1;
}
}
/* turn on/off mic-mute LED per capture hook by coef bit */
static void alc_hp_cap_micmute_update(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
if (spec->gen.micmute_led.led_value)
alc_update_coef_idx(codec, spec->mic_led_coef_idx,
spec->mic_led_coefbit_mask, spec->mic_led_coefbit_on);
else
alc_update_coef_idx(codec, spec->mic_led_coef_idx,
spec->mic_led_coefbit_mask, spec->mic_led_coefbit_off);
}
static void alc285_fixup_hp_coef_micmute_led(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
struct alc_spec *spec = codec->spec;
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->mic_led_coef_idx = 0x19;
spec->mic_led_coefbit_mask = 1<<13;
spec->mic_led_coefbit_on = 1<<13;
spec->mic_led_coefbit_off = 0;
snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
}
}
static void alc236_fixup_hp_coef_micmute_led(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
struct alc_spec *spec = codec->spec;
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->mic_led_coef_idx = 0x35;
spec->mic_led_coefbit_mask = 3<<2;
spec->mic_led_coefbit_on = 2<<2;
spec->mic_led_coefbit_off = 1<<2;
snd_hda_gen_add_micmute_led(codec, alc_hp_cap_micmute_update);
}
}
static void alc285_fixup_hp_mute_led(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
alc285_fixup_hp_mute_led_coefbit(codec, fix, action);
alc285_fixup_hp_coef_micmute_led(codec, fix, action);
}
static void alc236_fixup_hp_mute_led(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
alc236_fixup_hp_mute_led_coefbit(codec, fix, action);
alc236_fixup_hp_coef_micmute_led(codec, fix, action);
}
#if IS_REACHABLE(CONFIG_INPUT) #if IS_REACHABLE(CONFIG_INPUT)
static void gpio2_mic_hotkey_event(struct hda_codec *codec, static void gpio2_mic_hotkey_event(struct hda_codec *codec,
struct hda_jack_callback *event) struct hda_jack_callback *event)
...@@ -5964,6 +6078,8 @@ enum { ...@@ -5964,6 +6078,8 @@ enum {
ALC285_FIXUP_THINKPAD_HEADSET_JACK, ALC285_FIXUP_THINKPAD_HEADSET_JACK,
ALC294_FIXUP_ASUS_HPE, ALC294_FIXUP_ASUS_HPE,
ALC285_FIXUP_HP_GPIO_LED, ALC285_FIXUP_HP_GPIO_LED,
ALC285_FIXUP_HP_MUTE_LED,
ALC236_FIXUP_HP_MUTE_LED,
}; };
static const struct hda_fixup alc269_fixups[] = { static const struct hda_fixup alc269_fixups[] = {
...@@ -7089,6 +7205,14 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -7089,6 +7205,14 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
.v.func = alc285_fixup_hp_gpio_led, .v.func = alc285_fixup_hp_gpio_led,
}, },
[ALC285_FIXUP_HP_MUTE_LED] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc285_fixup_hp_mute_led,
},
[ALC236_FIXUP_HP_MUTE_LED] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc236_fixup_hp_mute_led,
},
}; };
static const struct snd_pci_quirk alc269_fixup_tbl[] = { static const struct snd_pci_quirk alc269_fixup_tbl[] = {
...@@ -7234,6 +7358,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -7234,6 +7358,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3), SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8736, "HP", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x877a, "HP", ALC285_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x877d, "HP", ALC236_FIXUP_HP_MUTE_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),
...@@ -7325,6 +7451,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -7325,6 +7451,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY), SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION), SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
......
...@@ -536,7 +536,7 @@ static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol, ...@@ -536,7 +536,7 @@ static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol,
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
mutex_lock(&ice->gpio_mutex); mutex_lock(&ice->gpio_mutex);
ucontrol->value.integer.value[0] = wm_get(ice, WM_ADC_MUX) & 0x1f; ucontrol->value.enumerated.item[0] = wm_get(ice, WM_ADC_MUX) & 0x1f;
mutex_unlock(&ice->gpio_mutex); mutex_unlock(&ice->gpio_mutex);
return 0; return 0;
} }
...@@ -550,7 +550,7 @@ static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol, ...@@ -550,7 +550,7 @@ static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
mutex_lock(&ice->gpio_mutex); mutex_lock(&ice->gpio_mutex);
oval = wm_get(ice, WM_ADC_MUX); oval = wm_get(ice, WM_ADC_MUX);
nval = (oval & 0xe0) | ucontrol->value.integer.value[0]; nval = (oval & 0xe0) | ucontrol->value.enumerated.item[0];
if (nval != oval) { if (nval != oval) {
wm_put(ice, WM_ADC_MUX, nval); wm_put(ice, WM_ADC_MUX, nval);
change = 1; change = 1;
......
...@@ -139,6 +139,7 @@ static int acp3x_i2s_hwparams(struct snd_pcm_substream *substream, ...@@ -139,6 +139,7 @@ static int acp3x_i2s_hwparams(struct snd_pcm_substream *substream,
rv_writel(adata->tdm_fmt, rtd->acp3x_base + frmt_reg); rv_writel(adata->tdm_fmt, rtd->acp3x_base + frmt_reg);
} }
val = rv_readl(rtd->acp3x_base + reg_val); val = rv_readl(rtd->acp3x_base + reg_val);
val &= ~ACP3x_ITER_IRER_SAMP_LEN_MASK;
val = val | (rtd->xfer_resolution << 3); val = val | (rtd->xfer_resolution << 3);
rv_writel(val, rtd->acp3x_base + reg_val); rv_writel(val, rtd->acp3x_base + reg_val);
return 0; return 0;
......
...@@ -76,6 +76,8 @@ ...@@ -76,6 +76,8 @@
#define ACP_POWERED_OFF 0x02 #define ACP_POWERED_OFF 0x02
#define ACP_POWER_OFF_IN_PROGRESS 0x03 #define ACP_POWER_OFF_IN_PROGRESS 0x03
#define ACP3x_ITER_IRER_SAMP_LEN_MASK 0x38
struct acp3x_platform_info { struct acp3x_platform_info {
u16 play_i2s_instance; u16 play_i2s_instance;
u16 cap_i2s_instance; u16 cap_i2s_instance;
......
...@@ -181,7 +181,7 @@ bcm63xx_pcm_pointer(struct snd_soc_component *component, ...@@ -181,7 +181,7 @@ bcm63xx_pcm_pointer(struct snd_soc_component *component,
snd_pcm_uframes_t x; snd_pcm_uframes_t x;
struct bcm63xx_runtime_data *prtd = substream->runtime->private_data; struct bcm63xx_runtime_data *prtd = substream->runtime->private_data;
if ((void *)prtd->dma_addr_next == NULL) if (!prtd->dma_addr_next)
prtd->dma_addr_next = substream->runtime->dma_addr; prtd->dma_addr_next = substream->runtime->dma_addr;
x = bytes_to_frames(substream->runtime, x = bytes_to_frames(substream->runtime,
......
...@@ -137,6 +137,9 @@ struct cs4270_private { ...@@ -137,6 +137,9 @@ struct cs4270_private {
/* power domain regulators */ /* power domain regulators */
struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
/* reset gpio */
struct gpio_desc *reset_gpio;
}; };
static const struct snd_soc_dapm_widget cs4270_dapm_widgets[] = { static const struct snd_soc_dapm_widget cs4270_dapm_widgets[] = {
...@@ -648,6 +651,22 @@ static const struct regmap_config cs4270_regmap = { ...@@ -648,6 +651,22 @@ static const struct regmap_config cs4270_regmap = {
.volatile_reg = cs4270_reg_is_volatile, .volatile_reg = cs4270_reg_is_volatile,
}; };
/**
* cs4270_i2c_remove - deinitialize the I2C interface of the CS4270
* @i2c_client: the I2C client object
*
* This function puts the chip into low power mode when the i2c device
* is removed.
*/
static int cs4270_i2c_remove(struct i2c_client *i2c_client)
{
struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client);
gpiod_set_value_cansleep(cs4270->reset_gpio, 0);
return 0;
}
/** /**
* cs4270_i2c_probe - initialize the I2C interface of the CS4270 * cs4270_i2c_probe - initialize the I2C interface of the CS4270
* @i2c_client: the I2C client object * @i2c_client: the I2C client object
...@@ -660,7 +679,6 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client, ...@@ -660,7 +679,6 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct cs4270_private *cs4270; struct cs4270_private *cs4270;
struct gpio_desc *reset_gpiod;
unsigned int val; unsigned int val;
int ret, i; int ret, i;
...@@ -679,10 +697,21 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client, ...@@ -679,10 +697,21 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
if (ret < 0) if (ret < 0)
return ret; return ret;
reset_gpiod = devm_gpiod_get_optional(&i2c_client->dev, "reset", /* reset the device */
GPIOD_OUT_HIGH); cs4270->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev, "reset",
if (PTR_ERR(reset_gpiod) == -EPROBE_DEFER) GPIOD_OUT_LOW);
return -EPROBE_DEFER; if (IS_ERR(cs4270->reset_gpio)) {
dev_dbg(&i2c_client->dev, "Error getting CS4270 reset GPIO\n");
return PTR_ERR(cs4270->reset_gpio);
}
if (cs4270->reset_gpio) {
dev_dbg(&i2c_client->dev, "Found reset GPIO\n");
gpiod_set_value_cansleep(cs4270->reset_gpio, 1);
}
/* Sleep 500ns before i2c communications */
ndelay(500);
cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap); cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap);
if (IS_ERR(cs4270->regmap)) if (IS_ERR(cs4270->regmap))
...@@ -735,6 +764,7 @@ static struct i2c_driver cs4270_i2c_driver = { ...@@ -735,6 +764,7 @@ static struct i2c_driver cs4270_i2c_driver = {
}, },
.id_table = cs4270_id, .id_table = cs4270_id,
.probe = cs4270_i2c_probe, .probe = cs4270_i2c_probe,
.remove = cs4270_i2c_remove,
}; };
module_i2c_driver(cs4270_i2c_driver); module_i2c_driver(cs4270_i2c_driver);
......
...@@ -3758,6 +3758,14 @@ static const struct dmi_system_id dmi_platform_data[] = { ...@@ -3758,6 +3758,14 @@ static const struct dmi_system_id dmi_platform_data[] = {
}, },
.driver_data = (void *)&kahlee_platform_data, .driver_data = (void *)&kahlee_platform_data,
}, },
{
.ident = "Medion E1239T",
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDION"),
DMI_MATCH(DMI_PRODUCT_NAME, "E1239T MD60568"),
},
.driver_data = (void *)&intel_braswell_platform_data,
},
{ } { }
}; };
......
...@@ -3703,7 +3703,7 @@ static const struct acpi_device_id rt5682_acpi_match[] = { ...@@ -3703,7 +3703,7 @@ static const struct acpi_device_id rt5682_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, rt5682_acpi_match); MODULE_DEVICE_TABLE(acpi, rt5682_acpi_match);
#endif #endif
static struct i2c_driver rt5682_i2c_driver = { static struct i2c_driver __maybe_unused rt5682_i2c_driver = {
.driver = { .driver = {
.name = "rt5682", .name = "rt5682",
.of_match_table = of_match_ptr(rt5682_of_match), .of_match_table = of_match_ptr(rt5682_of_match),
...@@ -3713,7 +3713,10 @@ static struct i2c_driver rt5682_i2c_driver = { ...@@ -3713,7 +3713,10 @@ static struct i2c_driver rt5682_i2c_driver = {
.shutdown = rt5682_i2c_shutdown, .shutdown = rt5682_i2c_shutdown,
.id_table = rt5682_i2c_id, .id_table = rt5682_i2c_id,
}; };
#ifdef CONFIG_I2C
module_i2c_driver(rt5682_i2c_driver); module_i2c_driver(rt5682_i2c_driver);
#endif
MODULE_DESCRIPTION("ASoC RT5682 driver"); MODULE_DESCRIPTION("ASoC RT5682 driver");
MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>"); MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
......
...@@ -50,6 +50,8 @@ static int sst_fill_and_send_cmd_unlocked(struct sst_data *drv, ...@@ -50,6 +50,8 @@ static int sst_fill_and_send_cmd_unlocked(struct sst_data *drv,
{ {
int ret = 0; int ret = 0;
WARN_ON(!mutex_is_locked(&drv->lock));
ret = sst_fill_byte_control(drv, ipc_msg, ret = sst_fill_byte_control(drv, ipc_msg,
block, task_id, pipe_id, len, cmd_data); block, task_id, pipe_id, len, cmd_data);
if (ret < 0) if (ret < 0)
...@@ -966,7 +968,9 @@ static int sst_set_be_modules(struct snd_soc_dapm_widget *w, ...@@ -966,7 +968,9 @@ static int sst_set_be_modules(struct snd_soc_dapm_widget *w,
dev_dbg(c->dev, "Enter: widget=%s\n", w->name); dev_dbg(c->dev, "Enter: widget=%s\n", w->name);
if (SND_SOC_DAPM_EVENT_ON(event)) { if (SND_SOC_DAPM_EVENT_ON(event)) {
mutex_lock(&drv->lock);
ret = sst_send_slot_map(drv); ret = sst_send_slot_map(drv);
mutex_unlock(&drv->lock);
if (ret) if (ret)
return ret; return ret;
ret = sst_send_pipe_module_params(w, k); ret = sst_send_pipe_module_params(w, k);
......
...@@ -223,9 +223,9 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst, ...@@ -223,9 +223,9 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst,
size_t mbox_data_len, const void *mbox_data, void **data, size_t mbox_data_len, const void *mbox_data, void **data,
bool large, bool fill_dsp, bool sync, bool response) bool large, bool fill_dsp, bool sync, bool response)
{ {
struct sst_block *block = NULL;
struct ipc_post *msg = NULL; struct ipc_post *msg = NULL;
struct ipc_dsp_hdr dsp_hdr; struct ipc_dsp_hdr dsp_hdr;
struct sst_block *block;
int ret = 0, pvt_id; int ret = 0, pvt_id;
pvt_id = sst_assign_pvt_id(sst); pvt_id = sst_assign_pvt_id(sst);
......
...@@ -254,7 +254,6 @@ static struct snd_soc_dai_link bdw_rt5650_dais[] = { ...@@ -254,7 +254,6 @@ static struct snd_soc_dai_link bdw_rt5650_dais[] = {
.no_pcm = 1, .no_pcm = 1,
.dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAIFMT_CBS_CFS,
.ignore_suspend = 1,
.ignore_pmdown_time = 1, .ignore_pmdown_time = 1,
.be_hw_params_fixup = broadwell_ssp0_fixup, .be_hw_params_fixup = broadwell_ssp0_fixup,
.ops = &bdw_rt5650_ops, .ops = &bdw_rt5650_ops,
......
...@@ -340,7 +340,6 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = { ...@@ -340,7 +340,6 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = {
.no_pcm = 1, .no_pcm = 1,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAIFMT_CBS_CFS,
.ignore_suspend = 1,
.ignore_pmdown_time = 1, .ignore_pmdown_time = 1,
.be_hw_params_fixup = broadwell_ssp0_fixup, .be_hw_params_fixup = broadwell_ssp0_fixup,
.ops = &bdw_rt5677_ops, .ops = &bdw_rt5677_ops,
......
...@@ -217,7 +217,6 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = { ...@@ -217,7 +217,6 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = {
.init = broadwell_rt286_codec_init, .init = broadwell_rt286_codec_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAIFMT_CBS_CFS,
.ignore_suspend = 1,
.ignore_pmdown_time = 1, .ignore_pmdown_time = 1,
.be_hw_params_fixup = broadwell_ssp0_fixup, .be_hw_params_fixup = broadwell_ssp0_fixup,
.ops = &broadwell_rt286_ops, .ops = &broadwell_rt286_ops,
......
...@@ -591,6 +591,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { ...@@ -591,6 +591,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
BYT_RT5640_SSP0_AIF1 | BYT_RT5640_SSP0_AIF1 |
BYT_RT5640_MCLK_EN), BYT_RT5640_MCLK_EN),
}, },
{
/* MPMAN MPWIN895CL */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MPMAN"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MPWIN8900CL"),
},
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
BYT_RT5640_MONO_SPEAKER |
BYT_RT5640_SSP0_AIF1 |
BYT_RT5640_MCLK_EN),
},
{ /* MSI S100 tablet */ { /* MSI S100 tablet */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."), DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
......
...@@ -162,7 +162,6 @@ static struct snd_soc_dai_link haswell_rt5640_dais[] = { ...@@ -162,7 +162,6 @@ static struct snd_soc_dai_link haswell_rt5640_dais[] = {
.no_pcm = 1, .no_pcm = 1,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAIFMT_CBS_CFS,
.ignore_suspend = 1,
.ignore_pmdown_time = 1, .ignore_pmdown_time = 1,
.be_hw_params_fixup = haswell_ssp0_fixup, .be_hw_params_fixup = haswell_ssp0_fixup,
.ops = &haswell_rt5640_ops, .ops = &haswell_rt5640_ops,
......
...@@ -78,7 +78,7 @@ struct q6asm_dai_data { ...@@ -78,7 +78,7 @@ struct q6asm_dai_data {
}; };
static const struct snd_pcm_hardware q6asm_dai_hardware_capture = { static const struct snd_pcm_hardware q6asm_dai_hardware_capture = {
.info = (SNDRV_PCM_INFO_MMAP | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BATCH |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_INTERLEAVED |
...@@ -100,7 +100,7 @@ static const struct snd_pcm_hardware q6asm_dai_hardware_capture = { ...@@ -100,7 +100,7 @@ static const struct snd_pcm_hardware q6asm_dai_hardware_capture = {
}; };
static struct snd_pcm_hardware q6asm_dai_hardware_playback = { static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
.info = (SNDRV_PCM_INFO_MMAP | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_BATCH |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_INTERLEAVED |
......
...@@ -295,12 +295,12 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai, ...@@ -295,12 +295,12 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai,
{ {
int ret = 0; int ret = 0;
if (!dai->started && if (!dai->started[substream->stream] &&
dai->driver->ops->startup) dai->driver->ops->startup)
ret = dai->driver->ops->startup(substream, dai); ret = dai->driver->ops->startup(substream, dai);
if (ret == 0) if (ret == 0)
dai->started = 1; dai->started[substream->stream] = 1;
return ret; return ret;
} }
...@@ -308,11 +308,11 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai, ...@@ -308,11 +308,11 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai,
void snd_soc_dai_shutdown(struct snd_soc_dai *dai, void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {
if (dai->started && if (dai->started[substream->stream] &&
dai->driver->ops->shutdown) dai->driver->ops->shutdown)
dai->driver->ops->shutdown(substream, dai); dai->driver->ops->shutdown(substream, dai);
dai->started = 0; dai->started[substream->stream] = 0;
} }
int snd_soc_dai_prepare(struct snd_soc_dai *dai, int snd_soc_dai_prepare(struct snd_soc_dai *dai,
......
...@@ -802,7 +802,13 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i, ...@@ -802,7 +802,13 @@ static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i,
val = max - val; val = max - val;
p->connect = !!val; p->connect = !!val;
} else { } else {
p->connect = 0; /* since a virtual mixer has no backing registers to
* decide which path to connect, it will try to match
* with initial state. This is to ensure
* that the default mixer choice will be
* correctly powered up during initialization.
*/
p->connect = invert;
} }
} }
......
...@@ -825,7 +825,7 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, ...@@ -825,7 +825,7 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol,
unsigned int regbase = mc->regbase; unsigned int regbase = mc->regbase;
unsigned int regcount = mc->regcount; unsigned int regcount = mc->regcount;
unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; unsigned int regwshift = component->val_bytes * BITS_PER_BYTE;
unsigned int regwmask = (1<<regwshift)-1; unsigned int regwmask = (1UL<<regwshift)-1;
unsigned int invert = mc->invert; unsigned int invert = mc->invert;
unsigned long mask = (1UL<<mc->nbits)-1; unsigned long mask = (1UL<<mc->nbits)-1;
long min = mc->min; long min = mc->min;
...@@ -874,7 +874,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, ...@@ -874,7 +874,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
unsigned int regbase = mc->regbase; unsigned int regbase = mc->regbase;
unsigned int regcount = mc->regcount; unsigned int regcount = mc->regcount;
unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; unsigned int regwshift = component->val_bytes * BITS_PER_BYTE;
unsigned int regwmask = (1<<regwshift)-1; unsigned int regwmask = (1UL<<regwshift)-1;
unsigned int invert = mc->invert; unsigned int invert = mc->invert;
unsigned long mask = (1UL<<mc->nbits)-1; unsigned long mask = (1UL<<mc->nbits)-1;
long max = mc->max; long max = mc->max;
......
...@@ -2324,7 +2324,8 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, ...@@ -2324,7 +2324,8 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
continue; continue;
ret = dpcm_do_trigger(dpcm, be_substream, cmd); ret = dpcm_do_trigger(dpcm, be_substream, cmd);
...@@ -2354,7 +2355,8 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, ...@@ -2354,7 +2355,8 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) &&
(be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
continue; continue;
if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream)) if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
......
...@@ -362,7 +362,7 @@ static int soc_tplg_add_kcontrol(struct soc_tplg *tplg, ...@@ -362,7 +362,7 @@ static int soc_tplg_add_kcontrol(struct soc_tplg *tplg,
struct snd_soc_component *comp = tplg->comp; struct snd_soc_component *comp = tplg->comp;
return soc_tplg_add_dcontrol(comp->card->snd_card, return soc_tplg_add_dcontrol(comp->card->snd_card,
comp->dev, k, NULL, comp, kcontrol); comp->dev, k, comp->name_prefix, comp, kcontrol);
} }
/* remove a mixer kcontrol */ /* remove a mixer kcontrol */
......
...@@ -597,7 +597,7 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev) ...@@ -597,7 +597,7 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev)
} }
if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) if (sdev->fw_state == SOF_FW_BOOT_COMPLETE)
dev_info(sdev->dev, "firmware boot complete\n"); dev_dbg(sdev->dev, "firmware boot complete\n");
else else
return -EIO; /* FW boots but fw_ready op failed */ return -EIO; /* FW boots but fw_ready op failed */
......
...@@ -1556,8 +1556,10 @@ static int stm32_sai_sub_probe(struct platform_device *pdev) ...@@ -1556,8 +1556,10 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
ret = snd_soc_register_component(&pdev->dev, &stm32_component, ret = snd_soc_register_component(&pdev->dev, &stm32_component,
&sai->cpu_dai_drv, 1); &sai->cpu_dai_drv, 1);
if (ret) if (ret) {
snd_dmaengine_pcm_unregister(&pdev->dev);
return ret; return ret;
}
if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
conf = &stm32_sai_pcm_config_spdif; conf = &stm32_sai_pcm_config_spdif;
......
...@@ -359,6 +359,14 @@ static const struct usbmix_name_map corsair_virtuoso_map[] = { ...@@ -359,6 +359,14 @@ static const struct usbmix_name_map corsair_virtuoso_map[] = {
{ 0 } { 0 }
}; };
/* Some mobos shipped with a dummy HD-audio show the invalid GET_MIN/GET_MAX
* response for Input Gain Pad (id=19, control=12). Skip it.
*/
static const struct usbmix_name_map asus_rog_map[] = {
{ 19, NULL, 12 }, /* FU, Input Gain Pad */
{}
};
/* /*
* Control map entries * Control map entries
*/ */
...@@ -488,6 +496,26 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = { ...@@ -488,6 +496,26 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
.id = USB_ID(0x1b1c, 0x0a42), .id = USB_ID(0x1b1c, 0x0a42),
.map = corsair_virtuoso_map, .map = corsair_virtuoso_map,
}, },
{ /* Gigabyte TRX40 Aorus Pro WiFi */
.id = USB_ID(0x0414, 0xa002),
.map = asus_rog_map,
},
{ /* ASUS ROG Zenith II */
.id = USB_ID(0x0b05, 0x1916),
.map = asus_rog_map,
},
{ /* ASUS ROG Strix */
.id = USB_ID(0x0b05, 0x1917),
.map = asus_rog_map,
},
{ /* MSI TRX40 Creator */
.id = USB_ID(0x0db0, 0x0d64),
.map = asus_rog_map,
},
{ /* MSI TRX40 */
.id = USB_ID(0x0db0, 0x543d),
.map = asus_rog_map,
},
{ 0 } /* terminator */ { 0 } /* terminator */
}; };
......
...@@ -3592,5 +3592,47 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), ...@@ -3592,5 +3592,47 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
} }
} }
}, },
{
/*
* Pioneer DJ DJM-250MK2
* PCM is 8 channels out @ 48 fixed (endpoints 0x01).
* The output from computer to the mixer is usable.
*
* The input (phono or line to computer) is not working.
* It should be at endpoint 0x82 and probably also 8 channels,
* but it seems that it works only with Pioneer proprietary software.
* Even on officially supported OS, the Audacity was unable to record
* and Mixxx to recognize the control vinyls.
*/
USB_DEVICE_VENDOR_SPEC(0x2b73, 0x0017),
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
.ifnum = QUIRK_ANY_INTERFACE,
.type = QUIRK_COMPOSITE,
.data = (const struct snd_usb_audio_quirk[]) {
{
.ifnum = 0,
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
.data = &(const struct audioformat) {
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
.channels = 8, // outputs
.iface = 0,
.altsetting = 1,
.altset_idx = 1,
.endpoint = 0x01,
.ep_attr = USB_ENDPOINT_XFER_ISOC|
USB_ENDPOINT_SYNC_ASYNC,
.rates = SNDRV_PCM_RATE_48000,
.rate_min = 48000,
.rate_max = 48000,
.nr_rates = 1,
.rate_table = (unsigned int[]) { 48000 }
}
},
{
.ifnum = -1
}
}
}
},
#undef USB_DEVICE_VENDOR_SPEC #undef USB_DEVICE_VENDOR_SPEC
...@@ -1827,6 +1827,7 @@ struct registration_quirk { ...@@ -1827,6 +1827,7 @@ struct registration_quirk {
static const struct registration_quirk registration_quirks[] = { static const struct registration_quirk registration_quirks[] = {
REG_QUIRK_ENTRY(0x0951, 0x16d8, 2), /* Kingston HyperX AMP */ REG_QUIRK_ENTRY(0x0951, 0x16d8, 2), /* Kingston HyperX AMP */
REG_QUIRK_ENTRY(0x0951, 0x16ed, 2), /* Kingston HyperX Cloud Alpha S */
{ 0 } /* terminator */ { 0 } /* terminator */
}; };
......
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