Commit 6f00d165 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'for-linus' into for-next

A back-merge of 5.15 branch into 5.16-devel branch for further
development of USB and ALSA core stuff that depends on 5.15 fixes.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parents 53451b6d aef454b4
...@@ -17891,7 +17891,8 @@ M: Olivier Moysan <olivier.moysan@foss.st.com> ...@@ -17891,7 +17891,8 @@ M: Olivier Moysan <olivier.moysan@foss.st.com>
M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> M: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers) L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/iio/adc/st,stm32-*.yaml F: Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml
F: Documentation/devicetree/bindings/sound/st,stm32-*.yaml
F: sound/soc/stm/ F: sound/soc/stm/
STM32 TIMER/LPTIMER DRIVERS STM32 TIMER/LPTIMER DRIVERS
......
...@@ -224,6 +224,7 @@ struct hda_codec { ...@@ -224,6 +224,7 @@ struct hda_codec {
#endif #endif
/* misc flags */ /* misc flags */
unsigned int configured:1; /* codec was configured */
unsigned int in_freeing:1; /* being released */ unsigned int in_freeing:1; /* being released */
unsigned int registered:1; /* codec was registered */ unsigned int registered:1; /* codec was registered */
unsigned int display_power_control:1; /* needs display power */ unsigned int display_power_control:1; /* needs display power */
......
...@@ -98,6 +98,7 @@ struct snd_rawmidi_file { ...@@ -98,6 +98,7 @@ struct snd_rawmidi_file {
struct snd_rawmidi *rmidi; struct snd_rawmidi *rmidi;
struct snd_rawmidi_substream *input; struct snd_rawmidi_substream *input;
struct snd_rawmidi_substream *output; struct snd_rawmidi_substream *output;
unsigned int user_pversion; /* supported protocol version */
}; };
struct snd_rawmidi_str { struct snd_rawmidi_str {
......
...@@ -784,6 +784,7 @@ struct snd_rawmidi_status { ...@@ -784,6 +784,7 @@ struct snd_rawmidi_status {
#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int) #define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int)
#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info) #define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info)
#define SNDRV_RAWMIDI_IOCTL_USER_PVERSION _IOW('W', 0x02, int)
#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params) #define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params)
#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status) #define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status)
#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int) #define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
......
...@@ -468,6 +468,76 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream, ...@@ -468,6 +468,76 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
} }
#endif /* CONFIG_X86_X32 */ #endif /* CONFIG_X86_X32 */
#ifdef __BIG_ENDIAN
typedef char __pad_before_u32[4];
typedef char __pad_after_u32[0];
#else
typedef char __pad_before_u32[0];
typedef char __pad_after_u32[4];
#endif
/* PCM 2.0.15 API definition had a bug in mmap control; it puts the avail_min
* at the wrong offset due to a typo in padding type.
* The bug hits only 32bit.
* A workaround for incorrect read/write is needed only in 32bit compat mode.
*/
struct __snd_pcm_mmap_control64_buggy {
__pad_before_u32 __pad1;
__u32 appl_ptr;
__pad_before_u32 __pad2; /* SiC! here is the bug */
__pad_before_u32 __pad3;
__u32 avail_min;
__pad_after_uframe __pad4;
};
static int snd_pcm_ioctl_sync_ptr_buggy(struct snd_pcm_substream *substream,
struct snd_pcm_sync_ptr __user *_sync_ptr)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_pcm_sync_ptr sync_ptr;
struct __snd_pcm_mmap_control64_buggy *sync_cp;
volatile struct snd_pcm_mmap_status *status;
volatile struct snd_pcm_mmap_control *control;
int err;
memset(&sync_ptr, 0, sizeof(sync_ptr));
sync_cp = (struct __snd_pcm_mmap_control64_buggy *)&sync_ptr.c.control;
if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
return -EFAULT;
if (copy_from_user(sync_cp, &(_sync_ptr->c.control), sizeof(*sync_cp)))
return -EFAULT;
status = runtime->status;
control = runtime->control;
if (sync_ptr.flags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
err = snd_pcm_hwsync(substream);
if (err < 0)
return err;
}
snd_pcm_stream_lock_irq(substream);
if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL)) {
err = pcm_lib_apply_appl_ptr(substream, sync_cp->appl_ptr);
if (err < 0) {
snd_pcm_stream_unlock_irq(substream);
return err;
}
} else {
sync_cp->appl_ptr = control->appl_ptr;
}
if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
control->avail_min = sync_cp->avail_min;
else
sync_cp->avail_min = control->avail_min;
sync_ptr.s.status.state = status->state;
sync_ptr.s.status.hw_ptr = status->hw_ptr;
sync_ptr.s.status.tstamp = status->tstamp;
sync_ptr.s.status.suspended_state = status->suspended_state;
sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
snd_pcm_stream_unlock_irq(substream);
if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
return -EFAULT;
return 0;
}
/* /*
*/ */
enum { enum {
...@@ -537,7 +607,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l ...@@ -537,7 +607,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
if (in_x32_syscall()) if (in_x32_syscall())
return snd_pcm_ioctl_sync_ptr_x32(substream, argp); return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
#endif /* CONFIG_X86_X32 */ #endif /* CONFIG_X86_X32 */
return snd_pcm_common_ioctl(file, substream, cmd, argp); return snd_pcm_ioctl_sync_ptr_buggy(substream, argp);
case SNDRV_PCM_IOCTL_HW_REFINE32: case SNDRV_PCM_IOCTL_HW_REFINE32:
return snd_pcm_ioctl_hw_params_compat(substream, 1, argp); return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
case SNDRV_PCM_IOCTL_HW_PARAMS32: case SNDRV_PCM_IOCTL_HW_PARAMS32:
......
...@@ -873,12 +873,21 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long ...@@ -873,12 +873,21 @@ static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long
return -EINVAL; return -EINVAL;
} }
} }
case SNDRV_RAWMIDI_IOCTL_USER_PVERSION:
if (get_user(rfile->user_pversion, (unsigned int __user *)arg))
return -EFAULT;
return 0;
case SNDRV_RAWMIDI_IOCTL_PARAMS: case SNDRV_RAWMIDI_IOCTL_PARAMS:
{ {
struct snd_rawmidi_params params; struct snd_rawmidi_params params;
if (copy_from_user(&params, argp, sizeof(struct snd_rawmidi_params))) if (copy_from_user(&params, argp, sizeof(struct snd_rawmidi_params)))
return -EFAULT; return -EFAULT;
if (rfile->user_pversion < SNDRV_PROTOCOL_VERSION(2, 0, 2)) {
params.mode = 0;
memset(params.reserved, 0, sizeof(params.reserved));
}
switch (params.stream) { switch (params.stream) {
case SNDRV_RAWMIDI_STREAM_OUTPUT: case SNDRV_RAWMIDI_STREAM_OUTPUT:
if (rfile->output == NULL) if (rfile->output == NULL)
......
...@@ -156,6 +156,8 @@ static int snd_seq_device_dev_free(struct snd_device *device) ...@@ -156,6 +156,8 @@ static int snd_seq_device_dev_free(struct snd_device *device)
struct snd_seq_device *dev = device->device_data; struct snd_seq_device *dev = device->device_data;
cancel_autoload_drivers(); cancel_autoload_drivers();
if (dev->private_free)
dev->private_free(dev);
put_device(&dev->dev); put_device(&dev->dev);
return 0; return 0;
} }
...@@ -183,11 +185,7 @@ static int snd_seq_device_dev_disconnect(struct snd_device *device) ...@@ -183,11 +185,7 @@ static int snd_seq_device_dev_disconnect(struct snd_device *device)
static void snd_seq_dev_release(struct device *dev) static void snd_seq_dev_release(struct device *dev)
{ {
struct snd_seq_device *sdev = to_seq_dev(dev); kfree(to_seq_dev(dev));
if (sdev->private_free)
sdev->private_free(sdev);
kfree(sdev);
} }
/* /*
......
...@@ -143,7 +143,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) ...@@ -143,7 +143,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
if (pointer_update) if (pointer_update)
pcsp_pointer_update(chip); pcsp_pointer_update(chip);
hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns)); hrtimer_forward_now(handle, ns_to_ktime(ns));
return HRTIMER_RESTART; return HRTIMER_RESTART;
} }
......
...@@ -276,10 +276,11 @@ static void __maybe_unused copy_message(u64 *frames, __be32 *buffer, ...@@ -276,10 +276,11 @@ static void __maybe_unused copy_message(u64 *frames, __be32 *buffer,
/* This is just for v2/v3 protocol. */ /* This is just for v2/v3 protocol. */
for (i = 0; i < data_blocks; ++i) { for (i = 0; i < data_blocks; ++i) {
*frames = (be32_to_cpu(buffer[1]) << 16) | *frames = be32_to_cpu(buffer[1]);
(be32_to_cpu(buffer[2]) >> 16); *frames <<= 16;
*frames |= be32_to_cpu(buffer[2]) >> 16;
++frames;
buffer += data_block_quadlets; buffer += data_block_quadlets;
frames++;
} }
} }
......
...@@ -421,7 +421,8 @@ int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset) ...@@ -421,7 +421,8 @@ int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset)
if (!full_reset) if (!full_reset)
goto skip_reset; goto skip_reset;
/* clear STATESTS */ /* clear STATESTS if not in reset */
if (snd_hdac_chip_readb(bus, GCTL) & AZX_GCTL_RESET)
snd_hdac_chip_writew(bus, STATESTS, STATESTS_INT_MASK); snd_hdac_chip_writew(bus, STATESTS, STATESTS_INT_MASK);
/* reset controller */ /* reset controller */
......
...@@ -298,29 +298,31 @@ int snd_hda_codec_configure(struct hda_codec *codec) ...@@ -298,29 +298,31 @@ int snd_hda_codec_configure(struct hda_codec *codec)
{ {
int err; int err;
if (codec->configured)
return 0;
if (is_generic_config(codec)) if (is_generic_config(codec))
codec->probe_id = HDA_CODEC_ID_GENERIC; codec->probe_id = HDA_CODEC_ID_GENERIC;
else else
codec->probe_id = 0; codec->probe_id = 0;
if (!device_is_registered(&codec->core.dev)) {
err = snd_hdac_device_register(&codec->core); err = snd_hdac_device_register(&codec->core);
if (err < 0) if (err < 0)
return err; return err;
}
if (!codec->preset) if (!codec->preset)
codec_bind_module(codec); codec_bind_module(codec);
if (!codec->preset) { if (!codec->preset) {
err = codec_bind_generic(codec); err = codec_bind_generic(codec);
if (err < 0) { if (err < 0) {
codec_err(codec, "Unable to bind the codec\n"); codec_dbg(codec, "Unable to bind the codec\n");
goto error; return err;
} }
} }
codec->configured = 1;
return 0; return 0;
error:
snd_hdac_device_unregister(&codec->core);
return err;
} }
EXPORT_SYMBOL_GPL(snd_hda_codec_configure); EXPORT_SYMBOL_GPL(snd_hda_codec_configure);
...@@ -791,6 +791,7 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec) ...@@ -791,6 +791,7 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
snd_array_free(&codec->nids); snd_array_free(&codec->nids);
remove_conn_list(codec); remove_conn_list(codec);
snd_hdac_regmap_exit(&codec->core); snd_hdac_regmap_exit(&codec->core);
codec->configured = 0;
} }
EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup_for_unbind); EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup_for_unbind);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <sound/core.h> #include <sound/core.h>
#include <sound/initval.h> #include <sound/initval.h>
#include "hda_controller.h" #include "hda_controller.h"
#include "hda_local.h"
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include "hda_controller_trace.h" #include "hda_controller_trace.h"
...@@ -1248,17 +1249,24 @@ EXPORT_SYMBOL_GPL(azx_probe_codecs); ...@@ -1248,17 +1249,24 @@ EXPORT_SYMBOL_GPL(azx_probe_codecs);
int azx_codec_configure(struct azx *chip) int azx_codec_configure(struct azx *chip)
{ {
struct hda_codec *codec, *next; struct hda_codec *codec, *next;
int success = 0;
/* use _safe version here since snd_hda_codec_configure() deregisters list_for_each_codec(codec, &chip->bus) {
* the device upon error and deletes itself from the bus list. if (!snd_hda_codec_configure(codec))
*/ success++;
}
if (success) {
/* unregister failed codecs if any codec has been probed */
list_for_each_codec_safe(codec, next, &chip->bus) { list_for_each_codec_safe(codec, next, &chip->bus) {
snd_hda_codec_configure(codec); if (!codec->configured) {
codec_err(codec, "Unable to configure, disabling\n");
snd_hdac_device_unregister(&codec->core);
}
}
} }
if (!azx_bus(chip)->num_codecs) return success ? 0 : -ENODEV;
return -ENODEV;
return 0;
} }
EXPORT_SYMBOL_GPL(azx_codec_configure); EXPORT_SYMBOL_GPL(azx_codec_configure);
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
/* 24 unused */ /* 24 unused */
#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
/* 27 unused */ #define AZX_DCAPS_RETRY_PROBE (1 << 27) /* retry probe if no codec is configured */
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */
#define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */ #define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */
#define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */ #define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */
......
...@@ -307,7 +307,8 @@ enum { ...@@ -307,7 +307,8 @@ enum {
/* quirks for AMD SB */ /* quirks for AMD SB */
#define AZX_DCAPS_PRESET_AMD_SB \ #define AZX_DCAPS_PRESET_AMD_SB \
(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_AMD_WORKAROUND |\ (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_AMD_WORKAROUND |\
AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME) AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME |\
AZX_DCAPS_RETRY_PROBE)
/* quirks for Nvidia */ /* quirks for Nvidia */
#define AZX_DCAPS_PRESET_NVIDIA \ #define AZX_DCAPS_PRESET_NVIDIA \
...@@ -1720,7 +1721,7 @@ static void azx_check_snoop_available(struct azx *chip) ...@@ -1720,7 +1721,7 @@ static void azx_check_snoop_available(struct azx *chip)
static void azx_probe_work(struct work_struct *work) static void azx_probe_work(struct work_struct *work)
{ {
struct hda_intel *hda = container_of(work, struct hda_intel, probe_work); struct hda_intel *hda = container_of(work, struct hda_intel, probe_work.work);
azx_probe_continue(&hda->chip); azx_probe_continue(&hda->chip);
} }
...@@ -1825,7 +1826,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -1825,7 +1826,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
} }
/* continue probing in work context as may trigger request module */ /* continue probing in work context as may trigger request module */
INIT_WORK(&hda->probe_work, azx_probe_work); INIT_DELAYED_WORK(&hda->probe_work, azx_probe_work);
*rchip = chip; *rchip = chip;
...@@ -2139,7 +2140,7 @@ static int azx_probe(struct pci_dev *pci, ...@@ -2139,7 +2140,7 @@ static int azx_probe(struct pci_dev *pci,
#endif #endif
if (schedule_probe) if (schedule_probe)
schedule_work(&hda->probe_work); schedule_delayed_work(&hda->probe_work, 0);
dev++; dev++;
if (chip->disabled) if (chip->disabled)
...@@ -2225,6 +2226,11 @@ static int azx_probe_continue(struct azx *chip) ...@@ -2225,6 +2226,11 @@ static int azx_probe_continue(struct azx *chip)
int dev = chip->dev_index; int dev = chip->dev_index;
int err; int err;
if (chip->disabled || hda->init_failed)
return -EIO;
if (hda->probe_retry)
goto probe_retry;
to_hda_bus(bus)->bus_probing = 1; to_hda_bus(bus)->bus_probing = 1;
hda->probe_continued = 1; hda->probe_continued = 1;
...@@ -2286,11 +2292,21 @@ static int azx_probe_continue(struct azx *chip) ...@@ -2286,11 +2292,21 @@ static int azx_probe_continue(struct azx *chip)
#endif #endif
} }
#endif #endif
probe_retry:
if (bus->codec_mask && !(probe_only[dev] & 1)) { if (bus->codec_mask && !(probe_only[dev] & 1)) {
err = azx_codec_configure(chip); err = azx_codec_configure(chip);
if (err < 0) if (err) {
if ((chip->driver_caps & AZX_DCAPS_RETRY_PROBE) &&
++hda->probe_retry < 60) {
schedule_delayed_work(&hda->probe_work,
msecs_to_jiffies(1000));
return 0; /* keep things up */
}
dev_err(chip->card->dev, "Cannot probe codecs, giving up\n");
goto out_free; goto out_free;
} }
}
err = snd_card_register(chip->card); err = snd_card_register(chip->card);
if (err < 0) if (err < 0)
...@@ -2319,6 +2335,7 @@ static int azx_probe_continue(struct azx *chip) ...@@ -2319,6 +2335,7 @@ static int azx_probe_continue(struct azx *chip)
display_power(chip, false); display_power(chip, false);
complete_all(&hda->probe_wait); complete_all(&hda->probe_wait);
to_hda_bus(bus)->bus_probing = 0; to_hda_bus(bus)->bus_probing = 0;
hda->probe_retry = 0;
return 0; return 0;
} }
...@@ -2344,7 +2361,7 @@ static void azx_remove(struct pci_dev *pci) ...@@ -2344,7 +2361,7 @@ static void azx_remove(struct pci_dev *pci)
* device during cancel_work_sync() call. * device during cancel_work_sync() call.
*/ */
device_unlock(&pci->dev); device_unlock(&pci->dev);
cancel_work_sync(&hda->probe_work); cancel_delayed_work_sync(&hda->probe_work);
device_lock(&pci->dev); device_lock(&pci->dev);
snd_card_free(card); snd_card_free(card);
......
...@@ -14,7 +14,7 @@ struct hda_intel { ...@@ -14,7 +14,7 @@ struct hda_intel {
/* sync probing */ /* sync probing */
struct completion probe_wait; struct completion probe_wait;
struct work_struct probe_work; struct delayed_work probe_work;
/* card list (for power_save trigger) */ /* card list (for power_save trigger) */
struct list_head list; struct list_head list;
...@@ -30,6 +30,8 @@ struct hda_intel { ...@@ -30,6 +30,8 @@ struct hda_intel {
unsigned int freed:1; /* resources already released */ unsigned int freed:1; /* resources already released */
bool need_i915_power:1; /* the hda controller needs i915 power */ bool need_i915_power:1; /* the hda controller needs i915 power */
int probe_retry; /* being probe-retry */
}; };
#endif #endif
...@@ -526,6 +526,8 @@ static void alc_shutup_pins(struct hda_codec *codec) ...@@ -526,6 +526,8 @@ static void alc_shutup_pins(struct hda_codec *codec)
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
switch (codec->core.vendor_id) { switch (codec->core.vendor_id) {
case 0x10ec0236:
case 0x10ec0256:
case 0x10ec0283: case 0x10ec0283:
case 0x10ec0286: case 0x10ec0286:
case 0x10ec0288: case 0x10ec0288:
...@@ -2533,11 +2535,13 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { ...@@ -2533,11 +2535,13 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x65d2, "Clevo PB51R[CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x65e1, "Clevo PB51[ED][DF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x65e5, "Clevo PC50D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x65e5, "Clevo PC50D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x65f1, "Clevo PC50HS", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x67d1, "Clevo PB71[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x67e1, "Clevo PB71[DE][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x67e5, "Clevo PC70D[PRS](?:-D|-G)?", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x70d1, "Clevo PC70[ER][CDF]", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170", ALC1220_FIXUP_CLEVO_PB51ED_PINS), SND_PCI_QUIRK(0x1558, 0x7714, "Clevo X170SM", ALC1220_FIXUP_CLEVO_PB51ED_PINS),
SND_PCI_QUIRK(0x1558, 0x7715, "Clevo X170KM-G", ALC1220_FIXUP_CLEVO_PB51ED),
SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1558, 0x9501, "Clevo P950HR", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1558, 0x9506, "Clevo P955HQ", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1558, 0x9506, "Clevo P955HQ", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1558, 0x950a, "Clevo P955H[PR]", ALC1220_FIXUP_CLEVO_P950), SND_PCI_QUIRK(0x1558, 0x950a, "Clevo P955H[PR]", ALC1220_FIXUP_CLEVO_P950),
...@@ -3528,7 +3532,8 @@ static void alc256_shutup(struct hda_codec *codec) ...@@ -3528,7 +3532,8 @@ static void alc256_shutup(struct hda_codec *codec)
/* If disable 3k pulldown control for alc257, the Mic detection will not work correctly /* If disable 3k pulldown control for alc257, the Mic detection will not work correctly
* when booting with headset plugged. So skip setting it for the codec alc257 * when booting with headset plugged. So skip setting it for the codec alc257
*/ */
if (codec->core.vendor_id != 0x10ec0257) if (spec->codec_variant != ALC269_TYPE_ALC257 &&
spec->codec_variant != ALC269_TYPE_ALC256)
alc_update_coef_idx(codec, 0x46, 0, 3 << 12); alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
if (!spec->no_shutup_pins) if (!spec->no_shutup_pins)
...@@ -6449,6 +6454,24 @@ static void alc287_fixup_legion_15imhg05_speakers(struct hda_codec *codec, ...@@ -6449,6 +6454,24 @@ static void alc287_fixup_legion_15imhg05_speakers(struct hda_codec *codec,
/* for alc285_fixup_ideapad_s740_coef() */ /* for alc285_fixup_ideapad_s740_coef() */
#include "ideapad_s740_helper.c" #include "ideapad_s740_helper.c"
static void alc256_fixup_tongfang_reset_persistent_settings(struct hda_codec *codec,
const struct hda_fixup *fix,
int action)
{
/*
* A certain other OS sets these coeffs to different values. On at least one TongFang
* barebone these settings might survive even a cold reboot. So to restore a clean slate the
* values are explicitly reset to default here. Without this, the external microphone is
* always in a plugged-in state, while the internal microphone is always in an unplugged
* state, breaking the ability to use the internal microphone.
*/
alc_write_coef_idx(codec, 0x24, 0x0000);
alc_write_coef_idx(codec, 0x26, 0x0000);
alc_write_coef_idx(codec, 0x29, 0x3000);
alc_write_coef_idx(codec, 0x37, 0xfe05);
alc_write_coef_idx(codec, 0x45, 0x5089);
}
enum { enum {
ALC269_FIXUP_GPIO2, ALC269_FIXUP_GPIO2,
ALC269_FIXUP_SONY_VAIO, ALC269_FIXUP_SONY_VAIO,
...@@ -6663,7 +6686,8 @@ enum { ...@@ -6663,7 +6686,8 @@ enum {
ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS, ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS,
ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE, ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE,
ALC287_FIXUP_YOGA7_14ITL_SPEAKERS, ALC287_FIXUP_YOGA7_14ITL_SPEAKERS,
ALC287_FIXUP_13S_GEN2_SPEAKERS ALC287_FIXUP_13S_GEN2_SPEAKERS,
ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS,
}; };
static const struct hda_fixup alc269_fixups[] = { static const struct hda_fixup alc269_fixups[] = {
...@@ -8344,7 +8368,7 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -8344,7 +8368,7 @@ static const struct hda_fixup alc269_fixups[] = {
.v.verbs = (const struct hda_verb[]) { .v.verbs = (const struct hda_verb[]) {
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x24 }, { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
{ 0x20, AC_VERB_SET_PROC_COEF, 0x41 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x41 },
{ 0x20, AC_VERB_SET_PROC_COEF, 0xb020 }, { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
{ 0x20, AC_VERB_SET_PROC_COEF, 0x2 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x2 },
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0 }, { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
...@@ -8361,6 +8385,10 @@ static const struct hda_fixup alc269_fixups[] = { ...@@ -8361,6 +8385,10 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true, .chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MODE, .chain_id = ALC269_FIXUP_HEADSET_MODE,
}, },
[ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc256_fixup_tongfang_reset_persistent_settings,
},
}; };
static const struct snd_pci_quirk alc269_fixup_tbl[] = { static const struct snd_pci_quirk alc269_fixup_tbl[] = {
...@@ -8452,6 +8480,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -8452,6 +8480,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0a30, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC), SND_PCI_QUIRK(0x1028, 0x0a30, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
SND_PCI_QUIRK(0x1028, 0x0a58, "Dell", ALC255_FIXUP_DELL_HEADSET_MIC), SND_PCI_QUIRK(0x1028, 0x0a58, "Dell", ALC255_FIXUP_DELL_HEADSET_MIC),
SND_PCI_QUIRK(0x1028, 0x0a61, "Dell XPS 15 9510", ALC289_FIXUP_DUAL_SPK), SND_PCI_QUIRK(0x1028, 0x0a61, "Dell XPS 15 9510", ALC289_FIXUP_DUAL_SPK),
SND_PCI_QUIRK(0x1028, 0x0a62, "Dell Precision 5560", ALC289_FIXUP_DUAL_SPK),
SND_PCI_QUIRK(0x1028, 0x0a9d, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0a9e, "Dell Latitude 5430", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
...@@ -8789,6 +8820,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -8789,6 +8820,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS),
SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC), SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
...@@ -10166,6 +10198,9 @@ enum { ...@@ -10166,6 +10198,9 @@ enum {
ALC671_FIXUP_HP_HEADSET_MIC2, ALC671_FIXUP_HP_HEADSET_MIC2,
ALC662_FIXUP_ACER_X2660G_HEADSET_MODE, ALC662_FIXUP_ACER_X2660G_HEADSET_MODE,
ALC662_FIXUP_ACER_NITRO_HEADSET_MODE, ALC662_FIXUP_ACER_NITRO_HEADSET_MODE,
ALC668_FIXUP_ASUS_NO_HEADSET_MIC,
ALC668_FIXUP_HEADSET_MIC,
ALC668_FIXUP_MIC_DET_COEF,
}; };
static const struct hda_fixup alc662_fixups[] = { static const struct hda_fixup alc662_fixups[] = {
...@@ -10549,6 +10584,29 @@ static const struct hda_fixup alc662_fixups[] = { ...@@ -10549,6 +10584,29 @@ static const struct hda_fixup alc662_fixups[] = {
.chained = true, .chained = true,
.chain_id = ALC662_FIXUP_USI_FUNC .chain_id = ALC662_FIXUP_USI_FUNC
}, },
[ALC668_FIXUP_ASUS_NO_HEADSET_MIC] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x1b, 0x04a1112c },
{ }
},
.chained = true,
.chain_id = ALC668_FIXUP_HEADSET_MIC
},
[ALC668_FIXUP_HEADSET_MIC] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc269_fixup_headset_mic,
.chained = true,
.chain_id = ALC668_FIXUP_MIC_DET_COEF
},
[ALC668_FIXUP_MIC_DET_COEF] = {
.type = HDA_FIXUP_VERBS,
.v.verbs = (const struct hda_verb[]) {
{ 0x20, AC_VERB_SET_COEF_INDEX, 0x15 },
{ 0x20, AC_VERB_SET_PROC_COEF, 0x0d60 },
{}
},
},
}; };
static const struct snd_pci_quirk alc662_fixup_tbl[] = { static const struct snd_pci_quirk alc662_fixup_tbl[] = {
...@@ -10584,6 +10642,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { ...@@ -10584,6 +10642,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51), SND_PCI_QUIRK(0x1043, 0x177d, "ASUS N551", ALC668_FIXUP_ASUS_Nx51),
SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51), SND_PCI_QUIRK(0x1043, 0x17bd, "ASUS N751", ALC668_FIXUP_ASUS_Nx51),
SND_PCI_QUIRK(0x1043, 0x185d, "ASUS G551JW", ALC668_FIXUP_ASUS_NO_HEADSET_MIC),
SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8), SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71SL", ALC662_FIXUP_ASUS_MODE8),
SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
......
...@@ -1073,6 +1073,16 @@ static int fsl_esai_probe(struct platform_device *pdev) ...@@ -1073,6 +1073,16 @@ static int fsl_esai_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto err_pm_get_sync; goto err_pm_get_sync;
/*
* Register platform component before registering cpu dai for there
* is not defer probe for platform component in snd_soc_add_pcm_runtime().
*/
ret = imx_pcm_dma_init(pdev, IMX_ESAI_DMABUF_SIZE);
if (ret) {
dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
goto err_pm_get_sync;
}
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component, ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component,
&fsl_esai_dai, 1); &fsl_esai_dai, 1);
if (ret) { if (ret) {
...@@ -1082,12 +1092,6 @@ static int fsl_esai_probe(struct platform_device *pdev) ...@@ -1082,12 +1092,6 @@ static int fsl_esai_probe(struct platform_device *pdev)
INIT_WORK(&esai_priv->work, fsl_esai_hw_reset); INIT_WORK(&esai_priv->work, fsl_esai_hw_reset);
ret = imx_pcm_dma_init(pdev, IMX_ESAI_DMABUF_SIZE);
if (ret) {
dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
goto err_pm_get_sync;
}
return ret; return ret;
err_pm_get_sync: err_pm_get_sync:
......
...@@ -737,18 +737,23 @@ static int fsl_micfil_probe(struct platform_device *pdev) ...@@ -737,18 +737,23 @@ static int fsl_micfil_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
regcache_cache_only(micfil->regmap, true); regcache_cache_only(micfil->regmap, true);
/*
* Register platform component before registering cpu dai for there
* is not defer probe for platform component in snd_soc_add_pcm_runtime().
*/
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
if (ret) {
dev_err(&pdev->dev, "failed to pcm register\n");
return ret;
}
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_micfil_component, ret = devm_snd_soc_register_component(&pdev->dev, &fsl_micfil_component,
&fsl_micfil_dai, 1); &fsl_micfil_dai, 1);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register component %s\n", dev_err(&pdev->dev, "failed to register component %s\n",
fsl_micfil_component.name); fsl_micfil_component.name);
return ret;
} }
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
if (ret)
dev_err(&pdev->dev, "failed to pcm register\n");
return ret; return ret;
} }
......
...@@ -1152,11 +1152,10 @@ static int fsl_sai_probe(struct platform_device *pdev) ...@@ -1152,11 +1152,10 @@ static int fsl_sai_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto err_pm_get_sync; goto err_pm_get_sync;
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component, /*
&sai->cpu_dai_drv, 1); * Register platform component before registering cpu dai for there
if (ret) * is not defer probe for platform component in snd_soc_add_pcm_runtime().
goto err_pm_get_sync; */
if (sai->soc_data->use_imx_pcm) { if (sai->soc_data->use_imx_pcm) {
ret = imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE); ret = imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE);
if (ret) if (ret)
...@@ -1167,6 +1166,11 @@ static int fsl_sai_probe(struct platform_device *pdev) ...@@ -1167,6 +1166,11 @@ static int fsl_sai_probe(struct platform_device *pdev)
goto err_pm_get_sync; goto err_pm_get_sync;
} }
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
&sai->cpu_dai_drv, 1);
if (ret)
goto err_pm_get_sync;
return ret; return ret;
err_pm_get_sync: err_pm_get_sync:
......
...@@ -1434,16 +1434,20 @@ static int fsl_spdif_probe(struct platform_device *pdev) ...@@ -1434,16 +1434,20 @@ static int fsl_spdif_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
regcache_cache_only(spdif_priv->regmap, true); regcache_cache_only(spdif_priv->regmap, true);
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_spdif_component, /*
&spdif_priv->cpu_dai_drv, 1); * Register platform component before registering cpu dai for there
* is not defer probe for platform component in snd_soc_add_pcm_runtime().
*/
ret = imx_pcm_dma_init(pdev, IMX_SPDIF_DMABUF_SIZE);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); dev_err_probe(&pdev->dev, ret, "imx_pcm_dma_init failed\n");
goto err_pm_disable; goto err_pm_disable;
} }
ret = imx_pcm_dma_init(pdev, IMX_SPDIF_DMABUF_SIZE); ret = devm_snd_soc_register_component(&pdev->dev, &fsl_spdif_component,
&spdif_priv->cpu_dai_drv, 1);
if (ret) { if (ret) {
dev_err_probe(&pdev->dev, ret, "imx_pcm_dma_init failed\n"); dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
goto err_pm_disable; goto err_pm_disable;
} }
......
...@@ -1215,18 +1215,23 @@ static int fsl_xcvr_probe(struct platform_device *pdev) ...@@ -1215,18 +1215,23 @@ static int fsl_xcvr_probe(struct platform_device *pdev)
pm_runtime_enable(dev); pm_runtime_enable(dev);
regcache_cache_only(xcvr->regmap, true); regcache_cache_only(xcvr->regmap, true);
/*
* Register platform component before registering cpu dai for there
* is not defer probe for platform component in snd_soc_add_pcm_runtime().
*/
ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0);
if (ret) {
dev_err(dev, "failed to pcm register\n");
return ret;
}
ret = devm_snd_soc_register_component(dev, &fsl_xcvr_comp, ret = devm_snd_soc_register_component(dev, &fsl_xcvr_comp,
&fsl_xcvr_dai, 1); &fsl_xcvr_dai, 1);
if (ret) { if (ret) {
dev_err(dev, "failed to register component %s\n", dev_err(dev, "failed to register component %s\n",
fsl_xcvr_comp.name); fsl_xcvr_comp.name);
return ret;
} }
ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0);
if (ret)
dev_err(dev, "failed to pcm register\n");
return ret; return ret;
} }
......
...@@ -929,6 +929,11 @@ static int create_sdw_dailink(struct snd_soc_card *card, ...@@ -929,6 +929,11 @@ static int create_sdw_dailink(struct snd_soc_card *card,
cpus + *cpu_id, cpu_dai_num, cpus + *cpu_id, cpu_dai_num,
codecs, codec_num, codecs, codec_num,
NULL, &sdw_ops); NULL, &sdw_ops);
/*
* SoundWire DAILINKs use 'stream' functions and Bank Switch operations
* based on wait_for_completion(), tag them as 'nonatomic'.
*/
dai_links[*be_index].nonatomic = true;
ret = set_codec_init_func(card, link, dai_links + (*be_index)++, ret = set_codec_init_func(card, link, dai_links + (*be_index)++,
playback, group_id); playback, group_id);
......
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
config SND_SOC_MEDIATEK config SND_SOC_MEDIATEK
tristate tristate
select REGMAP_MMIO
config SND_SOC_MT2701 config SND_SOC_MT2701
tristate "ASoC support for Mediatek MT2701 chip" tristate "ASoC support for Mediatek MT2701 chip"
...@@ -188,7 +189,9 @@ config SND_SOC_MT8192_MT6359_RT1015_RT5682 ...@@ -188,7 +189,9 @@ config SND_SOC_MT8192_MT6359_RT1015_RT5682
config SND_SOC_MT8195 config SND_SOC_MT8195
tristate "ASoC support for Mediatek MT8195 chip" tristate "ASoC support for Mediatek MT8195 chip"
depends on ARCH_MEDIATEK || COMPILE_TEST depends on ARCH_MEDIATEK || COMPILE_TEST
depends on COMMON_CLK
select SND_SOC_MEDIATEK select SND_SOC_MEDIATEK
select MFD_SYSCON if SND_SOC_MT6359
help help
This adds ASoC platform driver support for Mediatek MT8195 chip This adds ASoC platform driver support for Mediatek MT8195 chip
that can be used with other codecs. that can be used with other codecs.
......
...@@ -334,9 +334,11 @@ int mtk_afe_suspend(struct snd_soc_component *component) ...@@ -334,9 +334,11 @@ int mtk_afe_suspend(struct snd_soc_component *component)
devm_kcalloc(dev, afe->reg_back_up_list_num, devm_kcalloc(dev, afe->reg_back_up_list_num,
sizeof(unsigned int), GFP_KERNEL); sizeof(unsigned int), GFP_KERNEL);
if (afe->reg_back_up) {
for (i = 0; i < afe->reg_back_up_list_num; i++) for (i = 0; i < afe->reg_back_up_list_num; i++)
regmap_read(regmap, afe->reg_back_up_list[i], regmap_read(regmap, afe->reg_back_up_list[i],
&afe->reg_back_up[i]); &afe->reg_back_up[i]);
}
afe->suspended = true; afe->suspended = true;
afe->runtime_suspend(dev); afe->runtime_suspend(dev);
...@@ -356,12 +358,13 @@ int mtk_afe_resume(struct snd_soc_component *component) ...@@ -356,12 +358,13 @@ int mtk_afe_resume(struct snd_soc_component *component)
afe->runtime_resume(dev); afe->runtime_resume(dev);
if (!afe->reg_back_up) if (!afe->reg_back_up) {
dev_dbg(dev, "%s no reg_backup\n", __func__); dev_dbg(dev, "%s no reg_backup\n", __func__);
} else {
for (i = 0; i < afe->reg_back_up_list_num; i++) for (i = 0; i < afe->reg_back_up_list_num; i++)
mtk_regmap_write(regmap, afe->reg_back_up_list[i], mtk_regmap_write(regmap, afe->reg_back_up_list[i],
afe->reg_back_up[i]); afe->reg_back_up[i]);
}
afe->suspended = false; afe->suspended = false;
return 0; return 0;
......
...@@ -424,7 +424,7 @@ static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd) ...@@ -424,7 +424,7 @@ static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL); return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
} }
static int mt8195_hdmitx_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
...@@ -902,7 +902,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { ...@@ -902,7 +902,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
.no_pcm = 1, .no_pcm = 1,
.dpcm_playback = 1, .dpcm_playback = 1,
.ops = &mt8195_dptx_ops, .ops = &mt8195_dptx_ops,
.be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup, .be_hw_params_fixup = mt8195_dptx_hw_params_fixup,
SND_SOC_DAILINK_REG(DPTX_BE), SND_SOC_DAILINK_REG(DPTX_BE),
}, },
[DAI_LINK_ETDM1_IN_BE] = { [DAI_LINK_ETDM1_IN_BE] = {
...@@ -953,7 +953,6 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { ...@@ -953,7 +953,6 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAIFMT_CBS_CFS,
.dpcm_playback = 1, .dpcm_playback = 1,
.be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup,
SND_SOC_DAILINK_REG(ETDM3_OUT_BE), SND_SOC_DAILINK_REG(ETDM3_OUT_BE),
}, },
[DAI_LINK_PCM1_BE] = { [DAI_LINK_PCM1_BE] = {
......
...@@ -371,7 +371,6 @@ int snd_sof_device_remove(struct device *dev) ...@@ -371,7 +371,6 @@ int snd_sof_device_remove(struct device *dev)
dev_warn(dev, "error: %d failed to prepare DSP for device removal", dev_warn(dev, "error: %d failed to prepare DSP for device removal",
ret); ret);
snd_sof_fw_unload(sdev);
snd_sof_ipc_free(sdev); snd_sof_ipc_free(sdev);
snd_sof_free_debug(sdev); snd_sof_free_debug(sdev);
snd_sof_free_trace(sdev); snd_sof_free_trace(sdev);
...@@ -394,8 +393,7 @@ int snd_sof_device_remove(struct device *dev) ...@@ -394,8 +393,7 @@ int snd_sof_device_remove(struct device *dev)
snd_sof_remove(sdev); snd_sof_remove(sdev);
/* release firmware */ /* release firmware */
release_firmware(pdata->fw); snd_sof_fw_unload(sdev);
pdata->fw = NULL;
return 0; return 0;
} }
......
...@@ -365,7 +365,14 @@ static int imx8_remove(struct snd_sof_dev *sdev) ...@@ -365,7 +365,14 @@ static int imx8_remove(struct snd_sof_dev *sdev)
/* on i.MX8 there is 1 to 1 match between type and BAR idx */ /* on i.MX8 there is 1 to 1 match between type and BAR idx */
static int imx8_get_bar_index(struct snd_sof_dev *sdev, u32 type) static int imx8_get_bar_index(struct snd_sof_dev *sdev, u32 type)
{ {
/* Only IRAM and SRAM bars are valid */
switch (type) {
case SOF_FW_BLK_TYPE_IRAM:
case SOF_FW_BLK_TYPE_SRAM:
return type; return type;
default:
return -EINVAL;
}
} }
static void imx8_ipc_msg_data(struct snd_sof_dev *sdev, static void imx8_ipc_msg_data(struct snd_sof_dev *sdev,
......
...@@ -228,7 +228,14 @@ static int imx8m_remove(struct snd_sof_dev *sdev) ...@@ -228,7 +228,14 @@ static int imx8m_remove(struct snd_sof_dev *sdev)
/* on i.MX8 there is 1 to 1 match between type and BAR idx */ /* on i.MX8 there is 1 to 1 match between type and BAR idx */
static int imx8m_get_bar_index(struct snd_sof_dev *sdev, u32 type) static int imx8m_get_bar_index(struct snd_sof_dev *sdev, u32 type)
{ {
/* Only IRAM and SRAM bars are valid */
switch (type) {
case SOF_FW_BLK_TYPE_IRAM:
case SOF_FW_BLK_TYPE_SRAM:
return type; return type;
default:
return -EINVAL;
}
} }
static void imx8m_ipc_msg_data(struct snd_sof_dev *sdev, static void imx8m_ipc_msg_data(struct snd_sof_dev *sdev,
......
...@@ -729,10 +729,10 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev) ...@@ -729,10 +729,10 @@ int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev)
ret = request_firmware(&plat_data->fw, fw_filename, sdev->dev); ret = request_firmware(&plat_data->fw, fw_filename, sdev->dev);
if (ret < 0) { if (ret < 0) {
dev_err(sdev->dev, "error: request firmware %s failed err: %d\n",
fw_filename, ret);
dev_err(sdev->dev, dev_err(sdev->dev,
"you may need to download the firmware from https://github.com/thesofproject/sof-bin/\n"); "error: sof firmware file is missing, you might need to\n");
dev_err(sdev->dev,
" download it from https://github.com/thesofproject/sof-bin/\n");
goto err; goto err;
} else { } else {
dev_dbg(sdev->dev, "request_firmware %s successful\n", dev_dbg(sdev->dev, "request_firmware %s successful\n",
...@@ -880,5 +880,7 @@ EXPORT_SYMBOL(snd_sof_run_firmware); ...@@ -880,5 +880,7 @@ EXPORT_SYMBOL(snd_sof_run_firmware);
void snd_sof_fw_unload(struct snd_sof_dev *sdev) void snd_sof_fw_unload(struct snd_sof_dev *sdev)
{ {
/* TODO: support module unloading at runtime */ /* TODO: support module unloading at runtime */
release_firmware(sdev->pdata->fw);
sdev->pdata->fw = NULL;
} }
EXPORT_SYMBOL(snd_sof_fw_unload); EXPORT_SYMBOL(snd_sof_fw_unload);
...@@ -530,7 +530,6 @@ void snd_sof_trace_notify_for_error(struct snd_sof_dev *sdev) ...@@ -530,7 +530,6 @@ void snd_sof_trace_notify_for_error(struct snd_sof_dev *sdev)
return; return;
if (sdev->dtrace_is_enabled) { if (sdev->dtrace_is_enabled) {
dev_err(sdev->dev, "error: waking up any trace sleepers\n");
sdev->dtrace_error = true; sdev->dtrace_error = true;
wake_up(&sdev->trace_sleep); wake_up(&sdev->trace_sleep);
} }
......
...@@ -122,9 +122,9 @@ static void xtensa_stack(struct snd_sof_dev *sdev, void *oops, u32 *stack, ...@@ -122,9 +122,9 @@ static void xtensa_stack(struct snd_sof_dev *sdev, void *oops, u32 *stack,
* 0x0049fbb0: 8000f2d0 0049fc00 6f6c6c61 00632e63 * 0x0049fbb0: 8000f2d0 0049fc00 6f6c6c61 00632e63
*/ */
for (i = 0; i < stack_words; i += 4) { for (i = 0; i < stack_words; i += 4) {
hex_dump_to_buffer(stack + i * 4, 16, 16, 4, hex_dump_to_buffer(stack + i, 16, 16, 4,
buf, sizeof(buf), false); buf, sizeof(buf), false);
dev_err(sdev->dev, "0x%08x: %s\n", stack_ptr + i, buf); dev_err(sdev->dev, "0x%08x: %s\n", stack_ptr + i * 4, buf);
} }
} }
......
...@@ -2450,6 +2450,8 @@ static int scarlett2_update_monitor_other(struct usb_mixer_interface *mixer) ...@@ -2450,6 +2450,8 @@ static int scarlett2_update_monitor_other(struct usb_mixer_interface *mixer)
err = scarlett2_usb_get_config(mixer, err = scarlett2_usb_get_config(mixer,
SCARLETT2_CONFIG_TALKBACK_MAP, SCARLETT2_CONFIG_TALKBACK_MAP,
1, &bitmap); 1, &bitmap);
if (err < 0)
return err;
for (i = 0; i < num_mixes; i++, bitmap >>= 1) for (i = 0; i < num_mixes; i++, bitmap >>= 1)
private->talkback_map[i] = bitmap & 1; private->talkback_map[i] = bitmap & 1;
} }
......
...@@ -77,6 +77,48 @@ ...@@ -77,6 +77,48 @@
/* E-Mu 0204 USB */ /* E-Mu 0204 USB */
{ USB_DEVICE_VENDOR_SPEC(0x041e, 0x3f19) }, { USB_DEVICE_VENDOR_SPEC(0x041e, 0x3f19) },
/*
* Creative Technology, Ltd Live! Cam Sync HD [VF0770]
* The device advertises 8 formats, but only a rate of 48kHz is honored by the
* hardware and 24 bits give chopped audio, so only report the one working
* combination.
*/
{
USB_DEVICE(0x041e, 0x4095),
.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 = 2,
.type = QUIRK_AUDIO_STANDARD_MIXER,
},
{
.ifnum = 3,
.type = QUIRK_AUDIO_FIXED_ENDPOINT,
.data = &(const struct audioformat) {
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels = 2,
.fmt_bits = 16,
.iface = 3,
.altsetting = 4,
.altset_idx = 4,
.endpoint = 0x82,
.ep_attr = 0x05,
.rates = SNDRV_PCM_RATE_48000,
.rate_min = 48000,
.rate_max = 48000,
.nr_rates = 1,
.rate_table = (unsigned int[]) { 48000 },
},
},
{
.ifnum = -1
},
},
},
},
/* /*
* HP Wireless Audio * HP Wireless Audio
* When not ignored, causes instability issues for some users, forcing them to * When not ignored, causes instability issues for some users, forcing them to
......
...@@ -1884,6 +1884,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { ...@@ -1884,6 +1884,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_GET_SAMPLE_RATE), QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */ DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
QUIRK_FLAG_GET_SAMPLE_RATE), QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */
QUIRK_FLAG_IGNORE_CTL_ERROR),
DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */
QUIRK_FLAG_GET_SAMPLE_RATE), QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */ DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */
...@@ -1900,6 +1902,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { ...@@ -1900,6 +1902,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY), QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY),
VENDOR_FLG(0x07fd, /* MOTU */ VENDOR_FLG(0x07fd, /* MOTU */
QUIRK_FLAG_VALIDATE_RATES), QUIRK_FLAG_VALIDATE_RATES),
VENDOR_FLG(0x1235, /* Focusrite Novation */
QUIRK_FLAG_VALIDATE_RATES),
VENDOR_FLG(0x152a, /* Thesycon devices */ VENDOR_FLG(0x152a, /* Thesycon devices */
QUIRK_FLAG_DSD_RAW), QUIRK_FLAG_DSD_RAW),
VENDOR_FLG(0x1de7, /* Phoenix Audio */ VENDOR_FLG(0x1de7, /* Phoenix Audio */
......
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