Merge branch 'for-linus' into for-next

Back-merge of devel branch for further fixes of memalloc helpers.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2022-11-16 12:54:02 +01:00
commit d69d137e56
79 changed files with 597 additions and 279 deletions

View file

@ -414,6 +414,7 @@ TripleX Chung <xxx.phy@gmail.com> <triplex@zh-kernel.org>
TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn> TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn>
Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com> Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com>
Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws> Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws>
Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com>
Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Uwe Kleine-König <ukleinek@strlen.de> Uwe Kleine-König <ukleinek@strlen.de>

View file

@ -8,7 +8,7 @@ title: Audio codec controlled by ChromeOS EC
maintainers: maintainers:
- Cheng-Yi Chiang <cychiang@chromium.org> - Cheng-Yi Chiang <cychiang@chromium.org>
- Tzung-Bi Shih <tzungbi@google.com> - Tzung-Bi Shih <tzungbi@kernel.org>
description: | description: |
Google's ChromeOS EC codec is a digital mic codec provided by the Google's ChromeOS EC codec is a digital mic codec provided by the

View file

@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Realtek rt1015p codec devicetree bindings title: Realtek rt1015p codec devicetree bindings
maintainers: maintainers:
- Tzung-Bi Shih <tzungbi@google.com> - Tzung-Bi Shih <tzungbi@kernel.org>
description: | description: |
Rt1015p is a rt1015 variant which does not support I2C and Rt1015p is a rt1015 variant which does not support I2C and

View file

@ -4906,7 +4906,7 @@ F: drivers/platform/chrome/
CHROMEOS EC CODEC DRIVER CHROMEOS EC CODEC DRIVER
M: Cheng-Yi Chiang <cychiang@chromium.org> M: Cheng-Yi Chiang <cychiang@chromium.org>
M: Tzung-Bi Shih <tzungbi@google.com> M: Tzung-Bi Shih <tzungbi@kernel.org>
R: Guenter Roeck <groeck@chromium.org> R: Guenter Roeck <groeck@chromium.org>
L: chrome-platform@lists.linux.dev L: chrome-platform@lists.linux.dev
S: Maintained S: Maintained

View file

@ -138,6 +138,7 @@ int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace); int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, bool add_on_replace);
int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id); int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id); int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl, const char *name);
int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active); int snd_ctl_activate_id(struct snd_card *card, struct snd_ctl_elem_id *id, int active);
struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid); struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id); struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);

View file

@ -177,6 +177,7 @@ void asoc_simple_convert_fixup(struct asoc_simple_data *data,
struct snd_pcm_hw_params *params); struct snd_pcm_hw_params *params);
void asoc_simple_parse_convert(struct device_node *np, char *prefix, void asoc_simple_parse_convert(struct device_node *np, char *prefix,
struct asoc_simple_data *data); struct asoc_simple_data *data);
bool asoc_simple_is_convert_required(const struct asoc_simple_data *data);
int asoc_simple_parse_routing(struct snd_soc_card *card, int asoc_simple_parse_routing(struct snd_soc_card *card,
char *prefix); char *prefix);

View file

@ -36,6 +36,10 @@ enum sof_ipc_ext_data {
SOF_IPC_EXT_USER_ABI_INFO = 4, SOF_IPC_EXT_USER_ABI_INFO = 4,
}; };
/* Build u32 number in format MMmmmppp */
#define SOF_FW_VER(MAJOR, MINOR, PATCH) ((uint32_t)( \
((MAJOR) << 24) | ((MINOR) << 12) | (PATCH)))
/* FW version - SOF_IPC_GLB_VERSION */ /* FW version - SOF_IPC_GLB_VERSION */
struct sof_ipc_fw_version { struct sof_ipc_fw_version {
struct sof_ipc_hdr hdr; struct sof_ipc_hdr hdr;

View file

@ -147,6 +147,7 @@ static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index,
return rc; return rc;
} }
/* Returns 1 if added, 0 for otherwise; don't return a negative value! */
/* FIXME: look at device node refcounting */ /* FIXME: look at device node refcounting */
static int i2sbus_add_dev(struct macio_dev *macio, static int i2sbus_add_dev(struct macio_dev *macio,
struct i2sbus_control *control, struct i2sbus_control *control,
@ -213,7 +214,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
* either as the second one in that case is just a modem. */ * either as the second one in that case is just a modem. */
if (!ok) { if (!ok) {
kfree(dev); kfree(dev);
return -ENODEV; return 0;
} }
mutex_init(&dev->lock); mutex_init(&dev->lock);
@ -302,6 +303,10 @@ static int i2sbus_add_dev(struct macio_dev *macio,
if (soundbus_add_one(&dev->sound)) { if (soundbus_add_one(&dev->sound)) {
printk(KERN_DEBUG "i2sbus: device registration error!\n"); printk(KERN_DEBUG "i2sbus: device registration error!\n");
if (dev->sound.ofdev.dev.kobj.state_initialized) {
soundbus_dev_put(&dev->sound);
return 0;
}
goto err; goto err;
} }

View file

@ -402,8 +402,10 @@ int pxa2xx_ac97_hw_probe(struct platform_device *dev)
goto err_clk2; goto err_clk2;
irq = platform_get_irq(dev, 0); irq = platform_get_irq(dev, 0);
if (!irq) if (irq < 0) {
ret = irq;
goto err_irq; goto err_irq;
}
ret = request_irq(irq, pxa2xx_ac97_irq, 0, "AC97", NULL); ret = request_irq(irq, pxa2xx_ac97_irq, 0, "AC97", NULL);
if (ret < 0) if (ret < 0)

View file

@ -753,6 +753,29 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
} }
EXPORT_SYMBOL(snd_ctl_rename_id); EXPORT_SYMBOL(snd_ctl_rename_id);
/**
* snd_ctl_rename - rename the control on the card
* @card: the card instance
* @kctl: the control to rename
* @name: the new name
*
* Renames the specified control on the card to the new name.
*
* Make sure to take the control write lock - down_write(&card->controls_rwsem).
*/
void snd_ctl_rename(struct snd_card *card, struct snd_kcontrol *kctl,
const char *name)
{
remove_hash_entries(card, kctl);
if (strscpy(kctl->id.name, name, sizeof(kctl->id.name)) < 0)
pr_warn("ALSA: Renamed control new name '%s' truncated to '%s'\n",
name, kctl->id.name);
add_hash_entries(card, kctl);
}
EXPORT_SYMBOL(snd_ctl_rename);
#ifndef CONFIG_SND_CTL_FAST_LOOKUP #ifndef CONFIG_SND_CTL_FAST_LOOKUP
static struct snd_kcontrol * static struct snd_kcontrol *
snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid) snd_ctl_find_numid_slow(struct snd_card *card, unsigned int numid)

View file

@ -9,6 +9,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/dma-map-ops.h>
#include <linux/genalloc.h> #include <linux/genalloc.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
@ -543,17 +544,17 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size)
sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir, sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir,
DEFAULT_GFP, 0); DEFAULT_GFP, 0);
if (!sgt) {
#ifdef CONFIG_SND_DMA_SGBUF #ifdef CONFIG_SND_DMA_SGBUF
if (!sgt && !get_dma_ops(dmab->dev.dev)) {
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG) if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG)
dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK;
else else
dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK; dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK;
return snd_dma_sg_fallback_alloc(dmab, size); return snd_dma_sg_fallback_alloc(dmab, size);
#else
return NULL;
#endif
} }
#endif
if (!sgt)
return NULL;
dmab->dev.need_sync = dma_need_sync(dmab->dev.dev, dmab->dev.need_sync = dma_need_sync(dmab->dev.dev,
sg_dma_address(sgt->sgl)); sg_dma_address(sgt->sgl));
@ -857,7 +858,7 @@ static const struct snd_malloc_ops snd_dma_noncoherent_ops = {
/* /*
* Entry points * Entry points
*/ */
static const struct snd_malloc_ops *dma_ops[] = { static const struct snd_malloc_ops *snd_dma_ops[] = {
[SNDRV_DMA_TYPE_CONTINUOUS] = &snd_dma_continuous_ops, [SNDRV_DMA_TYPE_CONTINUOUS] = &snd_dma_continuous_ops,
[SNDRV_DMA_TYPE_VMALLOC] = &snd_dma_vmalloc_ops, [SNDRV_DMA_TYPE_VMALLOC] = &snd_dma_vmalloc_ops,
#ifdef CONFIG_HAS_DMA #ifdef CONFIG_HAS_DMA
@ -883,7 +884,7 @@ static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab)
if (WARN_ON_ONCE(!dmab)) if (WARN_ON_ONCE(!dmab))
return NULL; return NULL;
if (WARN_ON_ONCE(dmab->dev.type <= SNDRV_DMA_TYPE_UNKNOWN || if (WARN_ON_ONCE(dmab->dev.type <= SNDRV_DMA_TYPE_UNKNOWN ||
dmab->dev.type >= ARRAY_SIZE(dma_ops))) dmab->dev.type >= ARRAY_SIZE(snd_dma_ops)))
return NULL; return NULL;
return dma_ops[dmab->dev.type]; return snd_dma_ops[dmab->dev.type];
} }

View file

@ -346,8 +346,10 @@ static int add_widget_node(struct kobject *parent, hda_nid_t nid,
return -ENOMEM; return -ENOMEM;
kobject_init(kobj, &widget_ktype); kobject_init(kobj, &widget_ktype);
err = kobject_add(kobj, parent, "%02x", nid); err = kobject_add(kobj, parent, "%02x", nid);
if (err < 0) if (err < 0) {
kobject_put(kobj);
return err; return err;
}
err = sysfs_create_group(kobj, group); err = sysfs_create_group(kobj, group);
if (err < 0) { if (err < 0) {
kobject_put(kobj); kobject_put(kobj);

View file

@ -320,6 +320,11 @@ static const struct config_entry config_table[] = {
{} {}
} }
}, },
{
.flags = FLAG_SOF,
.device = 0x34c8,
.codec_hid = &essx_83x6,
},
{ {
.flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE,
.device = 0x34c8, .device = 0x34c8,

View file

@ -2656,11 +2656,18 @@ EXPORT_SYMBOL(snd_ac97_resume);
*/ */
static void set_ctl_name(char *dst, const char *src, const char *suffix) static void set_ctl_name(char *dst, const char *src, const char *suffix)
{ {
if (suffix) const size_t msize = SNDRV_CTL_ELEM_ID_NAME_MAXLEN;
sprintf(dst, "%s %s", src, suffix);
else if (suffix) {
strcpy(dst, src); if (snprintf(dst, msize, "%s %s", src, suffix) >= msize)
} pr_warn("ALSA: AC97 control name '%s %s' truncated to '%s'\n",
src, suffix, dst);
} else {
if (strscpy(dst, src, msize) < 0)
pr_warn("ALSA: AC97 control name '%s' truncated to '%s'\n",
src, dst);
}
}
/* remove the control with the given name and optional suffix */ /* remove the control with the given name and optional suffix */
static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name,
@ -2687,8 +2694,11 @@ static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src,
const char *dst, const char *suffix) const char *dst, const char *suffix)
{ {
struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix); struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix);
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
if (kctl) { if (kctl) {
set_ctl_name(kctl->id.name, dst, suffix); set_ctl_name(name, dst, suffix);
snd_ctl_rename(ac97->bus->card, kctl, name);
return 0; return 0;
} }
return -ENOENT; return -ENOENT;
@ -2707,11 +2717,17 @@ static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1,
const char *s2, const char *suffix) const char *s2, const char *suffix)
{ {
struct snd_kcontrol *kctl1, *kctl2; struct snd_kcontrol *kctl1, *kctl2;
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
kctl1 = ctl_find(ac97, s1, suffix); kctl1 = ctl_find(ac97, s1, suffix);
kctl2 = ctl_find(ac97, s2, suffix); kctl2 = ctl_find(ac97, s2, suffix);
if (kctl1 && kctl2) { if (kctl1 && kctl2) {
set_ctl_name(kctl1->id.name, s2, suffix); set_ctl_name(name, s2, suffix);
set_ctl_name(kctl2->id.name, s1, suffix); snd_ctl_rename(ac97->bus->card, kctl1, name);
set_ctl_name(name, s1, suffix);
snd_ctl_rename(ac97->bus->card, kctl2, name);
return 0; return 0;
} }
return -ENOENT; return -ENOENT;

View file

@ -141,7 +141,7 @@ struct snd_vortex {
#ifndef CHIP_AU8810 #ifndef CHIP_AU8810
stream_t dma_wt[NR_WT]; stream_t dma_wt[NR_WT];
wt_voice_t wt_voice[NR_WT]; /* WT register cache. */ wt_voice_t wt_voice[NR_WT]; /* WT register cache. */
char mixwt[(NR_WT / NR_WTPB) * 6]; /* WT mixin objects */ s8 mixwt[(NR_WT / NR_WTPB) * 6]; /* WT mixin objects */
#endif #endif
/* Global resources */ /* Global resources */
@ -235,8 +235,8 @@ static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v);
static void vortex_connect_default(vortex_t * vortex, int en); static void vortex_connect_default(vortex_t * vortex, int en);
static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch,
int dir, int type, int subdev); int dir, int type, int subdev);
static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, static int vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out,
int restype); int restype);
#ifndef CHIP_AU8810 #ifndef CHIP_AU8810
static int vortex_wt_allocroute(vortex_t * vortex, int dma, int nr_ch); static int vortex_wt_allocroute(vortex_t * vortex, int dma, int nr_ch);
static void vortex_wt_connect(vortex_t * vortex, int en); static void vortex_wt_connect(vortex_t * vortex, int en);

View file

@ -1998,7 +1998,7 @@ static const int resnum[VORTEX_RESOURCE_LAST] =
out: Mean checkout if != 0. Else mean Checkin resource. out: Mean checkout if != 0. Else mean Checkin resource.
restype: Indicates type of resource to be checked in or out. restype: Indicates type of resource to be checked in or out.
*/ */
static char static int
vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype) vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
{ {
int i, qty = resnum[restype], resinuse = 0; int i, qty = resnum[restype], resinuse = 0;

View file

@ -720,7 +720,7 @@ static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
{ {
struct snd_kcontrol *kctl = ctl_find(card, src); struct snd_kcontrol *kctl = ctl_find(card, src);
if (kctl) { if (kctl) {
strcpy(kctl->id.name, dst); snd_ctl_rename(card, kctl, dst);
return 0; return 0;
} }
return -ENOENT; return -ENOENT;

View file

@ -1767,7 +1767,7 @@ static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
{ {
struct snd_kcontrol *kctl = ctl_find(card, src); struct snd_kcontrol *kctl = ctl_find(card, src);
if (kctl) { if (kctl) {
strcpy(kctl->id.name, dst); snd_ctl_rename(card, kctl, dst);
return 0; return 0;
} }
return -ENOENT; return -ENOENT;

View file

@ -485,8 +485,8 @@ static int intel_ml_lctl_set_power(struct azx *chip, int state)
int timeout; int timeout;
/* /*
* the codecs are sharing the first link setting by default * Changes to LCTL.SCF are only needed for the first multi-link dealing
* If other links are enabled for stream, they need similar fix * with external codecs
*/ */
val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL); val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
val &= ~AZX_ML_LCTL_SPA; val &= ~AZX_ML_LCTL_SPA;
@ -513,7 +513,7 @@ static void intel_init_lctl(struct azx *chip)
/* 0. check lctl register value is correct or not */ /* 0. check lctl register value is correct or not */
val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL); val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
/* if SCF is already set, let's use it */ /* only perform additional configurations if the SCF is initially based on 6MHz */
if ((val & AZX_ML_LCTL_SCF) != 0) if ((val & AZX_ML_LCTL_SCF) != 0)
return; return;
@ -531,7 +531,7 @@ static void intel_init_lctl(struct azx *chip)
if (ret) if (ret)
goto set_spa; goto set_spa;
/* 2. update SCF to select a properly audio clock*/ /* 2. update SCF to select an audio clock different from 6MHz */
val &= ~AZX_ML_LCTL_SCF; val &= ~AZX_ML_LCTL_SCF;
val |= intel_get_lctl_scf(chip); val |= intel_get_lctl_scf(chip);
writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL); writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
@ -2711,6 +2711,9 @@ static const struct pci_device_id azx_ids[] = {
{ PCI_DEVICE(0x1002, 0xab28), { PCI_DEVICE(0x1002, 0xab28),
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
AZX_DCAPS_PM_RUNTIME }, AZX_DCAPS_PM_RUNTIME },
{ PCI_DEVICE(0x1002, 0xab30),
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
AZX_DCAPS_PM_RUNTIME },
{ PCI_DEVICE(0x1002, 0xab38), { PCI_DEVICE(0x1002, 0xab38),
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
AZX_DCAPS_PM_RUNTIME }, AZX_DCAPS_PM_RUNTIME },

View file

@ -1306,6 +1306,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI), SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI), SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI),
SND_PCI_QUIRK(0x3842, 0x1038, "EVGA X99 Classified", QUIRK_R3DI), SND_PCI_QUIRK(0x3842, 0x1038, "EVGA X99 Classified", QUIRK_R3DI),
SND_PCI_QUIRK(0x3842, 0x1055, "EVGA Z390 DARK", QUIRK_R3DI),
SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D), SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D), SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5), SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5),

View file

@ -2142,7 +2142,7 @@ static void rename_ctl(struct hda_codec *codec, const char *oldname,
kctl = snd_hda_find_mixer_ctl(codec, oldname); kctl = snd_hda_find_mixer_ctl(codec, oldname);
if (kctl) if (kctl)
strcpy(kctl->id.name, newname); snd_ctl_rename(codec->card, kctl, newname);
} }
static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec, static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
@ -9323,6 +9323,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
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(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED),
SND_PCI_QUIRK(0x103c, 0x896d, "HP ZBook Firefly 16 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x896e, "HP EliteBook x360 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8971, "HP EliteBook 830 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8972, "HP EliteBook 840 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
@ -9341,6 +9342,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89aa, "HP EliteBook 630 G9", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ac, "HP EliteBook 640 G9", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ae, "HP EliteBook 650 G9", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89c0, "HP ZBook Power 15.6 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
@ -9402,6 +9404,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401),
SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401),
SND_PCI_QUIRK(0x1043, 0x1f12, "ASUS UM5302", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1f92, "ASUS ROG Flow X16", ALC289_FIXUP_ASUS_GA401),
SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2), SND_PCI_QUIRK(0x1043, 0x3030, "ASUS ZN270IE", ALC256_FIXUP_ASUS_AIO_GPIO2),
SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
@ -9433,6 +9436,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_AMP),
SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_AMP),
SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_AMP),
SND_PCI_QUIRK(0x144d, 0xc1a3, "Samsung Galaxy Book Pro (NP935XDB-KC1SE)", ALC298_FIXUP_SAMSUNG_AMP),
SND_PCI_QUIRK(0x144d, 0xc1a6, "Samsung Galaxy Book Pro 360 (NP930QBD)", ALC298_FIXUP_SAMSUNG_AMP),
SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8), SND_PCI_QUIRK(0x144d, 0xc740, "Samsung Ativ book 8 (NP870Z5G)", ALC269_FIXUP_ATIV_BOOK_8),
SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_AMP),
SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP),
@ -9606,6 +9611,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), SND_PCI_QUIRK(0x17aa, 0x511f, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK), SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK),
SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS),
SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20), SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20),

View file

@ -433,7 +433,7 @@ struct hdsp_midi {
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;
char istimer; /* timer in use */ signed char istimer; /* timer in use */
struct timer_list timer; struct timer_list timer;
spinlock_t lock; spinlock_t lock;
int pending; int pending;
@ -480,7 +480,7 @@ struct hdsp {
pid_t playback_pid; pid_t playback_pid;
int running; int running;
int system_sample_rate; int system_sample_rate;
const char *channel_map; const signed char *channel_map;
int dev; int dev;
int irq; int irq;
unsigned long port; unsigned long port;
@ -502,7 +502,7 @@ struct hdsp {
where the data for that channel can be read/written from/to. where the data for that channel can be read/written from/to.
*/ */
static const char channel_map_df_ss[HDSP_MAX_CHANNELS] = { static const signed char channel_map_df_ss[HDSP_MAX_CHANNELS] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25 18, 19, 20, 21, 22, 23, 24, 25
}; };
@ -517,7 +517,7 @@ static const char channel_map_mf_ss[HDSP_MAX_CHANNELS] = { /* Multiface */
-1, -1, -1, -1, -1, -1, -1, -1 -1, -1, -1, -1, -1, -1, -1, -1
}; };
static const char channel_map_ds[HDSP_MAX_CHANNELS] = { static const signed char channel_map_ds[HDSP_MAX_CHANNELS] = {
/* ADAT channels are remapped */ /* ADAT channels are remapped */
1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
/* channels 12 and 13 are S/PDIF */ /* channels 12 and 13 are S/PDIF */
@ -526,7 +526,7 @@ static const char channel_map_ds[HDSP_MAX_CHANNELS] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
}; };
static const char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = { static const signed char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
/* ADAT channels */ /* ADAT channels */
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
/* SPDIF */ /* SPDIF */
@ -540,7 +540,7 @@ static const char channel_map_H9632_ss[HDSP_MAX_CHANNELS] = {
-1, -1 -1, -1
}; };
static const char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = { static const signed char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
/* ADAT */ /* ADAT */
1, 3, 5, 7, 1, 3, 5, 7,
/* SPDIF */ /* SPDIF */
@ -554,7 +554,7 @@ static const char channel_map_H9632_ds[HDSP_MAX_CHANNELS] = {
-1, -1, -1, -1, -1, -1 -1, -1, -1, -1, -1, -1
}; };
static const char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = { static const signed char channel_map_H9632_qs[HDSP_MAX_CHANNELS] = {
/* ADAT is disabled in this mode */ /* ADAT is disabled in this mode */
/* SPDIF */ /* SPDIF */
8, 9, 8, 9,
@ -3939,7 +3939,7 @@ static snd_pcm_uframes_t snd_hdsp_hw_pointer(struct snd_pcm_substream *substream
return hdsp_hw_pointer(hdsp); return hdsp_hw_pointer(hdsp);
} }
static char *hdsp_channel_buffer_location(struct hdsp *hdsp, static signed char *hdsp_channel_buffer_location(struct hdsp *hdsp,
int stream, int stream,
int channel) int channel)
@ -3964,7 +3964,7 @@ static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream,
void __user *src, unsigned long count) void __user *src, unsigned long count)
{ {
struct hdsp *hdsp = snd_pcm_substream_chip(substream); struct hdsp *hdsp = snd_pcm_substream_chip(substream);
char *channel_buf; signed char *channel_buf;
if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES)) if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES))
return -EINVAL; return -EINVAL;
@ -3982,7 +3982,7 @@ static int snd_hdsp_playback_copy_kernel(struct snd_pcm_substream *substream,
void *src, unsigned long count) void *src, unsigned long count)
{ {
struct hdsp *hdsp = snd_pcm_substream_chip(substream); struct hdsp *hdsp = snd_pcm_substream_chip(substream);
char *channel_buf; signed char *channel_buf;
channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel); channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel);
if (snd_BUG_ON(!channel_buf)) if (snd_BUG_ON(!channel_buf))
@ -3996,7 +3996,7 @@ static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream,
void __user *dst, unsigned long count) void __user *dst, unsigned long count)
{ {
struct hdsp *hdsp = snd_pcm_substream_chip(substream); struct hdsp *hdsp = snd_pcm_substream_chip(substream);
char *channel_buf; signed char *channel_buf;
if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES)) if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES))
return -EINVAL; return -EINVAL;
@ -4014,7 +4014,7 @@ static int snd_hdsp_capture_copy_kernel(struct snd_pcm_substream *substream,
void *dst, unsigned long count) void *dst, unsigned long count)
{ {
struct hdsp *hdsp = snd_pcm_substream_chip(substream); struct hdsp *hdsp = snd_pcm_substream_chip(substream);
char *channel_buf; signed char *channel_buf;
channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel); channel_buf = hdsp_channel_buffer_location(hdsp, substream->pstr->stream, channel);
if (snd_BUG_ON(!channel_buf)) if (snd_BUG_ON(!channel_buf))
@ -4028,7 +4028,7 @@ static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream,
unsigned long count) unsigned long count)
{ {
struct hdsp *hdsp = snd_pcm_substream_chip(substream); struct hdsp *hdsp = snd_pcm_substream_chip(substream);
char *channel_buf; signed char *channel_buf;
channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
if (snd_BUG_ON(!channel_buf)) if (snd_BUG_ON(!channel_buf))

View file

@ -230,7 +230,7 @@ struct snd_rme9652 {
int last_spdif_sample_rate; /* so that we can catch externally ... */ int last_spdif_sample_rate; /* so that we can catch externally ... */
int last_adat_sample_rate; /* ... induced rate changes */ int last_adat_sample_rate; /* ... induced rate changes */
const char *channel_map; const signed char *channel_map;
struct snd_card *card; struct snd_card *card;
struct snd_pcm *pcm; struct snd_pcm *pcm;
@ -247,12 +247,12 @@ struct snd_rme9652 {
where the data for that channel can be read/written from/to. where the data for that channel can be read/written from/to.
*/ */
static const char channel_map_9652_ss[26] = { static const signed char channel_map_9652_ss[26] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25 18, 19, 20, 21, 22, 23, 24, 25
}; };
static const char channel_map_9636_ss[26] = { static const signed char channel_map_9636_ss[26] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
/* channels 16 and 17 are S/PDIF */ /* channels 16 and 17 are S/PDIF */
24, 25, 24, 25,
@ -260,7 +260,7 @@ static const char channel_map_9636_ss[26] = {
-1, -1, -1, -1, -1, -1, -1, -1 -1, -1, -1, -1, -1, -1, -1, -1
}; };
static const char channel_map_9652_ds[26] = { static const signed char channel_map_9652_ds[26] = {
/* ADAT channels are remapped */ /* ADAT channels are remapped */
1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23,
/* channels 12 and 13 are S/PDIF */ /* channels 12 and 13 are S/PDIF */
@ -269,7 +269,7 @@ static const char channel_map_9652_ds[26] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
}; };
static const char channel_map_9636_ds[26] = { static const signed char channel_map_9636_ds[26] = {
/* ADAT channels are remapped */ /* ADAT channels are remapped */
1, 3, 5, 7, 9, 11, 13, 15, 1, 3, 5, 7, 9, 11, 13, 15,
/* channels 8 and 9 are S/PDIF */ /* channels 8 and 9 are S/PDIF */
@ -1819,7 +1819,7 @@ static snd_pcm_uframes_t snd_rme9652_hw_pointer(struct snd_pcm_substream *substr
return rme9652_hw_pointer(rme9652); return rme9652_hw_pointer(rme9652);
} }
static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652, static signed char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
int stream, int stream,
int channel) int channel)
@ -1847,7 +1847,7 @@ static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream,
void __user *src, unsigned long count) void __user *src, unsigned long count)
{ {
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
char *channel_buf; signed char *channel_buf;
if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES)) if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES))
return -EINVAL; return -EINVAL;
@ -1867,7 +1867,7 @@ static int snd_rme9652_playback_copy_kernel(struct snd_pcm_substream *substream,
void *src, unsigned long count) void *src, unsigned long count)
{ {
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
char *channel_buf; signed char *channel_buf;
channel_buf = rme9652_channel_buffer_location(rme9652, channel_buf = rme9652_channel_buffer_location(rme9652,
substream->pstr->stream, substream->pstr->stream,
@ -1883,7 +1883,7 @@ static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream,
void __user *dst, unsigned long count) void __user *dst, unsigned long count)
{ {
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
char *channel_buf; signed char *channel_buf;
if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES)) if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES))
return -EINVAL; return -EINVAL;
@ -1903,7 +1903,7 @@ static int snd_rme9652_capture_copy_kernel(struct snd_pcm_substream *substream,
void *dst, unsigned long count) void *dst, unsigned long count)
{ {
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
char *channel_buf; signed char *channel_buf;
channel_buf = rme9652_channel_buffer_location(rme9652, channel_buf = rme9652_channel_buffer_location(rme9652,
substream->pstr->stream, substream->pstr->stream,
@ -1919,7 +1919,7 @@ static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream,
unsigned long count) unsigned long count)
{ {
struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
char *channel_buf; signed char *channel_buf;
channel_buf = rme9652_channel_buffer_location (rme9652, channel_buf = rme9652_channel_buffer_location (rme9652,
substream->pstr->stream, substream->pstr->stream,

View file

@ -45,6 +45,27 @@ static struct snd_soc_card acp6x_card = {
}; };
static const struct dmi_system_id yc_acp_quirk_table[] = { static const struct dmi_system_id yc_acp_quirk_table[] = {
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D0"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_NAME, "21D1"),
}
},
{ {
.driver_data = &acp6x_card, .driver_data = &acp6x_card,
.matches = { .matches = {
@ -185,6 +206,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"), DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"),
} }
}, },
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"),
DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"),
}
},
{} {}
}; };

View file

@ -1629,6 +1629,7 @@ config SND_SOC_TFA989X
config SND_SOC_TLV320ADC3XXX config SND_SOC_TLV320ADC3XXX
tristate "Texas Instruments TLV320ADC3001/3101 audio ADC" tristate "Texas Instruments TLV320ADC3001/3101 audio ADC"
depends on I2C depends on I2C
depends on GPIOLIB
help help
Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101 Enable support for Texas Instruments TLV320ADC3001 and TLV320ADC3101
ADCs. ADCs.

View file

@ -177,7 +177,7 @@
#define CX2072X_PLBK_DRC_PARM_LEN 9 #define CX2072X_PLBK_DRC_PARM_LEN 9
#define CX2072X_CLASSD_AMP_LEN 6 #define CX2072X_CLASSD_AMP_LEN 6
/* DAI interfae type */ /* DAI interface type */
#define CX2072X_DAI_HIFI 1 #define CX2072X_DAI_HIFI 1
#define CX2072X_DAI_DSP 2 #define CX2072X_DAI_DSP 2
#define CX2072X_DAI_DSP_PWM 3 /* 4 ch, including mic and AEC */ #define CX2072X_DAI_DSP_PWM 3 /* 4 ch, including mic and AEC */

View file

@ -136,14 +136,17 @@ enum {
#define REG_CGR3_GO1L_OFFSET 0 #define REG_CGR3_GO1L_OFFSET 0
#define REG_CGR3_GO1L_MASK (0x1f << REG_CGR3_GO1L_OFFSET) #define REG_CGR3_GO1L_MASK (0x1f << REG_CGR3_GO1L_OFFSET)
#define REG_CGR10_GIL_OFFSET 0
#define REG_CGR10_GIR_OFFSET 4
struct jz_icdc { struct jz_icdc {
struct regmap *regmap; struct regmap *regmap;
void __iomem *base; void __iomem *base;
struct clk *clk; struct clk *clk;
}; };
static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_dac_tlv, -2250, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv, 0, 150, 0);
static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_line_tlv, -1500, 600); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0);
static const struct snd_kcontrol_new jz4725b_codec_controls[] = { static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
SOC_DOUBLE_TLV("Master Playback Volume", SOC_DOUBLE_TLV("Master Playback Volume",
@ -151,11 +154,11 @@ static const struct snd_kcontrol_new jz4725b_codec_controls[] = {
REG_CGR1_GODL_OFFSET, REG_CGR1_GODL_OFFSET,
REG_CGR1_GODR_OFFSET, REG_CGR1_GODR_OFFSET,
0xf, 1, jz4725b_dac_tlv), 0xf, 1, jz4725b_dac_tlv),
SOC_DOUBLE_R_TLV("Master Capture Volume", SOC_DOUBLE_TLV("Master Capture Volume",
JZ4725B_CODEC_REG_CGR3, JZ4725B_CODEC_REG_CGR10,
JZ4725B_CODEC_REG_CGR2, REG_CGR10_GIL_OFFSET,
REG_CGR2_GO1R_OFFSET, REG_CGR10_GIR_OFFSET,
0x1f, 1, jz4725b_line_tlv), 0xf, 0, jz4725b_adc_tlv),
SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1, SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1,
REG_CR1_DAC_MUTE_OFFSET, 1, 1), REG_CR1_DAC_MUTE_OFFSET, 1, 1),
@ -180,7 +183,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(jz4725b_codec_adc_src_enum,
jz4725b_codec_adc_src_texts, jz4725b_codec_adc_src_texts,
jz4725b_codec_adc_src_values); jz4725b_codec_adc_src_values);
static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl = static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl =
SOC_DAPM_ENUM("Route", jz4725b_codec_adc_src_enum); SOC_DAPM_ENUM("ADC Source Capture Route", jz4725b_codec_adc_src_enum);
static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = { static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = {
SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1, SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1,
@ -225,7 +228,7 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_DAPM_ADC("ADC", "Capture",
JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1), JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1),
SND_SOC_DAPM_MUX("ADC Source", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MUX("ADC Source Capture Route", SND_SOC_NOPM, 0, 0,
&jz4725b_codec_adc_src_ctrl), &jz4725b_codec_adc_src_ctrl),
/* Mixer */ /* Mixer */
@ -236,7 +239,8 @@ static const struct snd_soc_dapm_widget jz4725b_codec_dapm_widgets[] = {
SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1, SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1,
REG_CR1_DACSEL_OFFSET, 0, NULL, 0), REG_CR1_DACSEL_OFFSET, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Line In", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("Line In", JZ4725B_CODEC_REG_PMR1,
REG_PMR1_SB_LIN_OFFSET, 1, NULL, 0),
SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1, SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1,
REG_CR1_HP_DIS_OFFSET, 1, NULL, 0), REG_CR1_HP_DIS_OFFSET, 1, NULL, 0),
@ -283,11 +287,11 @@ static const struct snd_soc_dapm_route jz4725b_codec_dapm_routes[] = {
{"Mixer", NULL, "DAC to Mixer"}, {"Mixer", NULL, "DAC to Mixer"},
{"Mixer to ADC", NULL, "Mixer"}, {"Mixer to ADC", NULL, "Mixer"},
{"ADC Source", "Mixer", "Mixer to ADC"}, {"ADC Source Capture Route", "Mixer", "Mixer to ADC"},
{"ADC Source", "Line In", "Line In"}, {"ADC Source Capture Route", "Line In", "Line In"},
{"ADC Source", "Mic 1", "Mic 1"}, {"ADC Source Capture Route", "Mic 1", "Mic 1"},
{"ADC Source", "Mic 2", "Mic 2"}, {"ADC Source Capture Route", "Mic 2", "Mic 2"},
{"ADC", NULL, "ADC Source"}, {"ADC", NULL, "ADC Source Capture Route"},
{"Out Stage", NULL, "Mixer"}, {"Out Stage", NULL, "Mixer"},
{"HP Out", NULL, "Out Stage"}, {"HP Out", NULL, "Out Stage"},

View file

@ -503,14 +503,14 @@ static int mt6660_i2c_probe(struct i2c_client *client)
dev_err(chip->dev, "read chip revision fail\n"); dev_err(chip->dev, "read chip revision fail\n");
goto probe_fail; goto probe_fail;
} }
pm_runtime_set_active(chip->dev);
pm_runtime_enable(chip->dev);
ret = devm_snd_soc_register_component(chip->dev, ret = devm_snd_soc_register_component(chip->dev,
&mt6660_component_driver, &mt6660_component_driver,
&mt6660_codec_dai, 1); &mt6660_codec_dai, 1);
if (!ret) { if (ret)
pm_runtime_set_active(chip->dev); pm_runtime_disable(chip->dev);
pm_runtime_enable(chip->dev);
}
return ret; return ret;

View file

@ -391,18 +391,18 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
unsigned int rx_mask, int slots, int slot_width) unsigned int rx_mask, int slots, int slot_width)
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
unsigned int val = 0, rx_slotnum; unsigned int cn = 0, cl = 0, rx_slotnum;
int ret = 0, first_bit; int ret = 0, first_bit;
switch (slots) { switch (slots) {
case 4: case 4:
val |= RT1019_I2S_TX_4CH; cn = RT1019_I2S_TX_4CH;
break; break;
case 6: case 6:
val |= RT1019_I2S_TX_6CH; cn = RT1019_I2S_TX_6CH;
break; break;
case 8: case 8:
val |= RT1019_I2S_TX_8CH; cn = RT1019_I2S_TX_8CH;
break; break;
case 2: case 2:
break; break;
@ -412,16 +412,16 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
switch (slot_width) { switch (slot_width) {
case 20: case 20:
val |= RT1019_I2S_DL_20; cl = RT1019_TDM_CL_20;
break; break;
case 24: case 24:
val |= RT1019_I2S_DL_24; cl = RT1019_TDM_CL_24;
break; break;
case 32: case 32:
val |= RT1019_I2S_DL_32; cl = RT1019_TDM_CL_32;
break; break;
case 8: case 8:
val |= RT1019_I2S_DL_8; cl = RT1019_TDM_CL_8;
break; break;
case 16: case 16:
break; break;
@ -470,8 +470,10 @@ static int rt1019_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
goto _set_tdm_err_; goto _set_tdm_err_;
} }
snd_soc_component_update_bits(component, RT1019_TDM_1,
RT1019_TDM_CL_MASK, cl);
snd_soc_component_update_bits(component, RT1019_TDM_2, snd_soc_component_update_bits(component, RT1019_TDM_2,
RT1019_I2S_CH_TX_MASK | RT1019_I2S_DF_MASK, val); RT1019_I2S_CH_TX_MASK, cn);
_set_tdm_err_: _set_tdm_err_:
return ret; return ret;

View file

@ -95,6 +95,12 @@
#define RT1019_TDM_BCLK_MASK (0x1 << 6) #define RT1019_TDM_BCLK_MASK (0x1 << 6)
#define RT1019_TDM_BCLK_NORM (0x0 << 6) #define RT1019_TDM_BCLK_NORM (0x0 << 6)
#define RT1019_TDM_BCLK_INV (0x1 << 6) #define RT1019_TDM_BCLK_INV (0x1 << 6)
#define RT1019_TDM_CL_MASK (0x7)
#define RT1019_TDM_CL_8 (0x4)
#define RT1019_TDM_CL_32 (0x3)
#define RT1019_TDM_CL_24 (0x2)
#define RT1019_TDM_CL_20 (0x1)
#define RT1019_TDM_CL_16 (0x0)
/* 0x0401 TDM Control-2 */ /* 0x0401 TDM Control-2 */
#define RT1019_I2S_CH_TX_MASK (0x3 << 6) #define RT1019_I2S_CH_TX_MASK (0x3 << 6)

View file

@ -50,6 +50,7 @@ static bool rt1308_volatile_register(struct device *dev, unsigned int reg)
case 0x3008: case 0x3008:
case 0x300a: case 0x300a:
case 0xc000: case 0xc000:
case 0xc710:
case 0xc860 ... 0xc863: case 0xc860 ... 0xc863:
case 0xc870 ... 0xc873: case 0xc870 ... 0xc873:
return true; return true;
@ -200,6 +201,7 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
{ {
struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev); struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
int ret = 0; int ret = 0;
unsigned int tmp;
if (rt1308->hw_init) if (rt1308->hw_init)
return 0; return 0;
@ -231,6 +233,10 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
/* sw reset */ /* sw reset */
regmap_write(rt1308->regmap, RT1308_SDW_RESET, 0); regmap_write(rt1308->regmap, RT1308_SDW_RESET, 0);
regmap_read(rt1308->regmap, 0xc710, &tmp);
rt1308->hw_ver = tmp;
dev_dbg(dev, "%s, hw_ver=0x%x\n", __func__, rt1308->hw_ver);
/* initial settings */ /* initial settings */
regmap_write(rt1308->regmap, 0xc103, 0xc0); regmap_write(rt1308->regmap, 0xc103, 0xc0);
regmap_write(rt1308->regmap, 0xc030, 0x17); regmap_write(rt1308->regmap, 0xc030, 0x17);
@ -246,8 +252,14 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
regmap_write(rt1308->regmap, 0xc062, 0x05); regmap_write(rt1308->regmap, 0xc062, 0x05);
regmap_write(rt1308->regmap, 0xc171, 0x07); regmap_write(rt1308->regmap, 0xc171, 0x07);
regmap_write(rt1308->regmap, 0xc173, 0x0d); regmap_write(rt1308->regmap, 0xc173, 0x0d);
regmap_write(rt1308->regmap, 0xc311, 0x7f); if (rt1308->hw_ver == RT1308_VER_C) {
regmap_write(rt1308->regmap, 0xc900, 0x90); regmap_write(rt1308->regmap, 0xc311, 0x7f);
regmap_write(rt1308->regmap, 0xc300, 0x09);
} else {
regmap_write(rt1308->regmap, 0xc311, 0x4f);
regmap_write(rt1308->regmap, 0xc300, 0x0b);
}
regmap_write(rt1308->regmap, 0xc900, 0x5a);
regmap_write(rt1308->regmap, 0xc1a0, 0x84); regmap_write(rt1308->regmap, 0xc1a0, 0x84);
regmap_write(rt1308->regmap, 0xc1a1, 0x01); regmap_write(rt1308->regmap, 0xc1a1, 0x01);
regmap_write(rt1308->regmap, 0xc360, 0x78); regmap_write(rt1308->regmap, 0xc360, 0x78);
@ -257,7 +269,6 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
regmap_write(rt1308->regmap, 0xc070, 0x00); regmap_write(rt1308->regmap, 0xc070, 0x00);
regmap_write(rt1308->regmap, 0xc100, 0xd7); regmap_write(rt1308->regmap, 0xc100, 0xd7);
regmap_write(rt1308->regmap, 0xc101, 0xd7); regmap_write(rt1308->regmap, 0xc101, 0xd7);
regmap_write(rt1308->regmap, 0xc300, 0x09);
if (rt1308->first_hw_init) { if (rt1308->first_hw_init) {
regcache_cache_bypass(rt1308->regmap, false); regcache_cache_bypass(rt1308->regmap, false);

View file

@ -139,10 +139,12 @@ static const struct reg_default rt1308_reg_defaults[] = {
{ 0x3005, 0x23 }, { 0x3005, 0x23 },
{ 0x3008, 0x02 }, { 0x3008, 0x02 },
{ 0x300a, 0x00 }, { 0x300a, 0x00 },
{ 0xc000 | (RT1308_DATA_PATH << 4), 0x00 },
{ 0xc003 | (RT1308_DAC_SET << 4), 0x00 }, { 0xc003 | (RT1308_DAC_SET << 4), 0x00 },
{ 0xc000 | (RT1308_POWER << 4), 0x00 }, { 0xc000 | (RT1308_POWER << 4), 0x00 },
{ 0xc001 | (RT1308_POWER << 4), 0x00 }, { 0xc001 | (RT1308_POWER << 4), 0x00 },
{ 0xc002 | (RT1308_POWER << 4), 0x00 }, { 0xc002 | (RT1308_POWER << 4), 0x00 },
{ 0xc000 | (RT1308_POWER_STATUS << 4), 0x00 },
}; };
#define RT1308_SDW_OFFSET 0xc000 #define RT1308_SDW_OFFSET 0xc000
@ -163,6 +165,7 @@ struct rt1308_sdw_priv {
bool first_hw_init; bool first_hw_init;
int rx_mask; int rx_mask;
int slots; int slots;
int hw_ver;
}; };
struct sdw_stream_data { struct sdw_stream_data {

View file

@ -286,4 +286,9 @@ enum {
RT1308_AIFS RT1308_AIFS
}; };
enum rt1308_hw_ver {
RT1308_VER_C = 2,
RT1308_VER_D
};
#endif /* end of _RT1308_H_ */ #endif /* end of _RT1308_H_ */

View file

@ -298,13 +298,14 @@ static int rt5514_spi_pcm_new(struct snd_soc_component *component,
} }
static const struct snd_soc_component_driver rt5514_spi_component = { static const struct snd_soc_component_driver rt5514_spi_component = {
.name = DRV_NAME, .name = DRV_NAME,
.probe = rt5514_spi_pcm_probe, .probe = rt5514_spi_pcm_probe,
.open = rt5514_spi_pcm_open, .open = rt5514_spi_pcm_open,
.hw_params = rt5514_spi_hw_params, .hw_params = rt5514_spi_hw_params,
.hw_free = rt5514_spi_hw_free, .hw_free = rt5514_spi_hw_free,
.pointer = rt5514_spi_pcm_pointer, .pointer = rt5514_spi_pcm_pointer,
.pcm_construct = rt5514_spi_pcm_new, .pcm_construct = rt5514_spi_pcm_new,
.legacy_dai_naming = 1,
}; };
/** /**

View file

@ -396,15 +396,16 @@ static int rt5677_spi_pcm_probe(struct snd_soc_component *component)
} }
static const struct snd_soc_component_driver rt5677_spi_dai_component = { static const struct snd_soc_component_driver rt5677_spi_dai_component = {
.name = DRV_NAME, .name = DRV_NAME,
.probe = rt5677_spi_pcm_probe, .probe = rt5677_spi_pcm_probe,
.open = rt5677_spi_pcm_open, .open = rt5677_spi_pcm_open,
.close = rt5677_spi_pcm_close, .close = rt5677_spi_pcm_close,
.hw_params = rt5677_spi_hw_params, .hw_params = rt5677_spi_hw_params,
.hw_free = rt5677_spi_hw_free, .hw_free = rt5677_spi_hw_free,
.prepare = rt5677_spi_prepare, .prepare = rt5677_spi_prepare,
.pointer = rt5677_spi_pcm_pointer, .pointer = rt5677_spi_pcm_pointer,
.pcm_construct = rt5677_spi_pcm_new, .pcm_construct = rt5677_spi_pcm_new,
.legacy_dai_naming = 1,
}; };
/* Select a suitable transfer command for the next transfer to ensure /* Select a suitable transfer command for the next transfer to ensure

View file

@ -1981,7 +1981,7 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
unsigned int rx_mask, int slots, int slot_width) unsigned int rx_mask, int slots, int slot_width)
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
unsigned int cl, val = 0; unsigned int cl, val = 0, tx_slotnum;
if (tx_mask || rx_mask) if (tx_mask || rx_mask)
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
@ -1990,6 +1990,16 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
snd_soc_component_update_bits(component, snd_soc_component_update_bits(component,
RT5682S_TDM_ADDA_CTRL_2, RT5682S_TDM_EN, 0); RT5682S_TDM_ADDA_CTRL_2, RT5682S_TDM_EN, 0);
/* Tx slot configuration */
tx_slotnum = hweight_long(tx_mask);
if (tx_slotnum) {
if (tx_slotnum > slots) {
dev_err(component->dev, "Invalid or oversized Tx slots.\n");
return -EINVAL;
}
val |= (tx_slotnum - 1) << RT5682S_TDM_ADC_DL_SFT;
}
switch (slots) { switch (slots) {
case 4: case 4:
val |= RT5682S_TDM_TX_CH_4; val |= RT5682S_TDM_TX_CH_4;
@ -2010,7 +2020,8 @@ static int rt5682s_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
} }
snd_soc_component_update_bits(component, RT5682S_TDM_CTRL, snd_soc_component_update_bits(component, RT5682S_TDM_CTRL,
RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK, val); RT5682S_TDM_TX_CH_MASK | RT5682S_TDM_RX_CH_MASK |
RT5682S_TDM_ADC_DL_MASK, val);
switch (slot_width) { switch (slot_width) {
case 8: case 8:

View file

@ -899,6 +899,7 @@
#define RT5682S_TDM_RX_CH_8 (0x3 << 8) #define RT5682S_TDM_RX_CH_8 (0x3 << 8)
#define RT5682S_TDM_ADC_LCA_MASK (0x7 << 4) #define RT5682S_TDM_ADC_LCA_MASK (0x7 << 4)
#define RT5682S_TDM_ADC_LCA_SFT 4 #define RT5682S_TDM_ADC_LCA_SFT 4
#define RT5682S_TDM_ADC_DL_MASK (0x3 << 0)
#define RT5682S_TDM_ADC_DL_SFT 0 #define RT5682S_TDM_ADC_DL_SFT 0
/* TDM control 2 (0x007a) */ /* TDM control 2 (0x007a) */

View file

@ -438,20 +438,13 @@ static int tas2764_set_dai_tdm_slot(struct snd_soc_dai *dai,
if (tx_mask == 0 || rx_mask != 0) if (tx_mask == 0 || rx_mask != 0)
return -EINVAL; return -EINVAL;
if (slots == 1) { left_slot = __ffs(tx_mask);
if (tx_mask != 1) tx_mask &= ~(1 << left_slot);
return -EINVAL; if (tx_mask == 0) {
left_slot = 0; right_slot = left_slot;
right_slot = 0;
} else { } else {
left_slot = __ffs(tx_mask); right_slot = __ffs(tx_mask);
tx_mask &= ~(1 << left_slot); tx_mask &= ~(1 << right_slot);
if (tx_mask == 0) {
right_slot = left_slot;
} else {
right_slot = __ffs(tx_mask);
tx_mask &= ~(1 << right_slot);
}
} }
if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)

View file

@ -395,21 +395,13 @@ static int tas2770_set_dai_tdm_slot(struct snd_soc_dai *dai,
if (tx_mask == 0 || rx_mask != 0) if (tx_mask == 0 || rx_mask != 0)
return -EINVAL; return -EINVAL;
if (slots == 1) { left_slot = __ffs(tx_mask);
if (tx_mask != 1) tx_mask &= ~(1 << left_slot);
return -EINVAL; if (tx_mask == 0) {
right_slot = left_slot;
left_slot = 0;
right_slot = 0;
} else { } else {
left_slot = __ffs(tx_mask); right_slot = __ffs(tx_mask);
tx_mask &= ~(1 << left_slot); tx_mask &= ~(1 << right_slot);
if (tx_mask == 0) {
right_slot = left_slot;
} else {
right_slot = __ffs(tx_mask);
tx_mask &= ~(1 << right_slot);
}
} }
if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)

View file

@ -380,20 +380,13 @@ static int tas2780_set_dai_tdm_slot(struct snd_soc_dai *dai,
if (tx_mask == 0 || rx_mask != 0) if (tx_mask == 0 || rx_mask != 0)
return -EINVAL; return -EINVAL;
if (slots == 1) { left_slot = __ffs(tx_mask);
if (tx_mask != 1) tx_mask &= ~(1 << left_slot);
return -EINVAL; if (tx_mask == 0) {
left_slot = 0; right_slot = left_slot;
right_slot = 0;
} else { } else {
left_slot = __ffs(tx_mask); right_slot = __ffs(tx_mask);
tx_mask &= ~(1 << left_slot); tx_mask &= ~(1 << right_slot);
if (tx_mask == 0) {
right_slot = left_slot;
} else {
right_slot = __ffs(tx_mask);
tx_mask &= ~(1 << right_slot);
}
} }
if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)

View file

@ -1449,7 +1449,7 @@ static struct i2c_driver adc3xxx_i2c_driver = {
.of_match_table = tlv320adc3xxx_of_match, .of_match_table = tlv320adc3xxx_of_match,
}, },
.probe_new = adc3xxx_i2c_probe, .probe_new = adc3xxx_i2c_probe,
.remove = adc3xxx_i2c_remove, .remove = __exit_p(adc3xxx_i2c_remove),
.id_table = adc3xxx_i2c_id, .id_table = adc3xxx_i2c_id,
}; };

View file

@ -2099,6 +2099,9 @@ static int wm5102_probe(struct platform_device *pdev)
regmap_update_bits(arizona->regmap, wm5102_digital_vu[i], regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
WM5102_DIG_VU, WM5102_DIG_VU); WM5102_DIG_VU, WM5102_DIG_VU);
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
"ADSP2 Compressed IRQ", wm5102_adsp2_irq, "ADSP2 Compressed IRQ", wm5102_adsp2_irq,
wm5102); wm5102);
@ -2131,9 +2134,6 @@ static int wm5102_probe(struct platform_device *pdev)
goto err_spk_irqs; goto err_spk_irqs;
} }
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
return ret; return ret;
err_spk_irqs: err_spk_irqs:
@ -2142,6 +2142,7 @@ err_dsp_irq:
arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0); arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5102); arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5102);
err_jack_codec_dev: err_jack_codec_dev:
pm_runtime_disable(&pdev->dev);
arizona_jack_codec_dev_remove(&wm5102->core); arizona_jack_codec_dev_remove(&wm5102->core);
return ret; return ret;

View file

@ -2457,6 +2457,9 @@ static int wm5110_probe(struct platform_device *pdev)
regmap_update_bits(arizona->regmap, wm5110_digital_vu[i], regmap_update_bits(arizona->regmap, wm5110_digital_vu[i],
WM5110_DIG_VU, WM5110_DIG_VU); WM5110_DIG_VU, WM5110_DIG_VU);
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
"ADSP2 Compressed IRQ", wm5110_adsp2_irq, "ADSP2 Compressed IRQ", wm5110_adsp2_irq,
wm5110); wm5110);
@ -2489,9 +2492,6 @@ static int wm5110_probe(struct platform_device *pdev)
goto err_spk_irqs; goto err_spk_irqs;
} }
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
return ret; return ret;
err_spk_irqs: err_spk_irqs:
@ -2500,6 +2500,7 @@ err_dsp_irq:
arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0); arizona_set_irq_wake(arizona, ARIZONA_IRQ_DSP_IRQ1, 0);
arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5110); arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5110);
err_jack_codec_dev: err_jack_codec_dev:
pm_runtime_disable(&pdev->dev);
arizona_jack_codec_dev_remove(&wm5110->core); arizona_jack_codec_dev_remove(&wm5110->core);
return ret; return ret;

View file

@ -1840,6 +1840,49 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
4, 1, 0, inmix_tlv), 4, 1, 0, inmix_tlv),
}; };
static int tp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
int ret, reg, val, mask;
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
ret = pm_runtime_resume_and_get(component->dev);
if (ret < 0) {
dev_err(component->dev, "Failed to resume device: %d\n", ret);
return ret;
}
reg = WM8962_ADDITIONAL_CONTROL_4;
if (!strcmp(w->name, "TEMP_HP")) {
mask = WM8962_TEMP_ENA_HP_MASK;
val = WM8962_TEMP_ENA_HP;
} else if (!strcmp(w->name, "TEMP_SPK")) {
mask = WM8962_TEMP_ENA_SPK_MASK;
val = WM8962_TEMP_ENA_SPK;
} else {
pm_runtime_put(component->dev);
return -EINVAL;
}
switch (event) {
case SND_SOC_DAPM_POST_PMD:
val = 0;
fallthrough;
case SND_SOC_DAPM_POST_PMU:
ret = snd_soc_component_update_bits(component, reg, mask, val);
break;
default:
WARN(1, "Invalid event %d\n", event);
pm_runtime_put(component->dev);
return -EINVAL;
}
pm_runtime_put(component->dev);
return 0;
}
static int cp_event(struct snd_soc_dapm_widget *w, static int cp_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event) struct snd_kcontrol *kcontrol, int event)
{ {
@ -2140,8 +2183,10 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT, SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT,
WM8962_DSP2_ENA_SHIFT, 0, dsp2_event, WM8962_DSP2_ENA_SHIFT, 0, dsp2_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("TEMP_HP", SND_SOC_NOPM, 0, 0, tp_event,
SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0), SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SUPPLY("TEMP_SPK", SND_SOC_NOPM, 0, 0, tp_event,
SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
inpgal, ARRAY_SIZE(inpgal)), inpgal, ARRAY_SIZE(inpgal)),
@ -3763,6 +3808,11 @@ static int wm8962_i2c_probe(struct i2c_client *i2c)
if (ret < 0) if (ret < 0)
goto err_pm_runtime; goto err_pm_runtime;
regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
WM8962_TEMP_ENA_HP_MASK, 0);
regmap_update_bits(wm8962->regmap, WM8962_ADDITIONAL_CONTROL_4,
WM8962_TEMP_ENA_SPK_MASK, 0);
regcache_cache_only(wm8962->regmap, true); regcache_cache_only(wm8962->regmap, true);
/* The drivers should power up as needed */ /* The drivers should power up as needed */

View file

@ -1161,6 +1161,9 @@ static int wm8997_probe(struct platform_device *pdev)
regmap_update_bits(arizona->regmap, wm8997_digital_vu[i], regmap_update_bits(arizona->regmap, wm8997_digital_vu[i],
WM8997_DIG_VU, WM8997_DIG_VU); WM8997_DIG_VU, WM8997_DIG_VU);
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
arizona_init_common(arizona); arizona_init_common(arizona);
ret = arizona_init_vol_limit(arizona); ret = arizona_init_vol_limit(arizona);
@ -1179,14 +1182,12 @@ static int wm8997_probe(struct platform_device *pdev)
goto err_spk_irqs; goto err_spk_irqs;
} }
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
return ret; return ret;
err_spk_irqs: err_spk_irqs:
arizona_free_spk_irqs(arizona); arizona_free_spk_irqs(arizona);
err_jack_codec_dev: err_jack_codec_dev:
pm_runtime_disable(&pdev->dev);
arizona_jack_codec_dev_remove(&wm8997->core); arizona_jack_codec_dev_remove(&wm8997->core);
return ret; return ret;

View file

@ -1232,7 +1232,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
} }
ret = pm_runtime_put_sync(&pdev->dev); ret = pm_runtime_put_sync(&pdev->dev);
if (ret < 0) if (ret < 0 && ret != -ENOSYS)
goto err_pm_get_sync; goto err_pm_get_sync;
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component, ret = devm_snd_soc_register_component(&pdev->dev, &fsl_asrc_component,

View file

@ -1069,7 +1069,7 @@ static int fsl_esai_probe(struct platform_device *pdev)
regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0); regmap_write(esai_priv->regmap, REG_ESAI_RSMB, 0);
ret = pm_runtime_put_sync(&pdev->dev); ret = pm_runtime_put_sync(&pdev->dev);
if (ret < 0) if (ret < 0 && ret != -ENOSYS)
goto err_pm_get_sync; goto err_pm_get_sync;
/* /*

View file

@ -1446,7 +1446,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
} }
ret = pm_runtime_put_sync(dev); ret = pm_runtime_put_sync(dev);
if (ret < 0) if (ret < 0 && ret != -ENOSYS)
goto err_pm_get_sync; goto err_pm_get_sync;
/* /*

View file

@ -417,7 +417,7 @@ static inline bool parse_as_dpcm_link(struct asoc_simple_priv *priv,
* or has convert-xxx property * or has convert-xxx property
*/ */
if ((of_get_child_count(codec_port) > 1) || if ((of_get_child_count(codec_port) > 1) ||
(adata->convert_rate || adata->convert_channels)) asoc_simple_is_convert_required(adata))
return true; return true;
return false; return false;

View file

@ -85,6 +85,21 @@ void asoc_simple_parse_convert(struct device_node *np,
} }
EXPORT_SYMBOL_GPL(asoc_simple_parse_convert); EXPORT_SYMBOL_GPL(asoc_simple_parse_convert);
/**
* asoc_simple_is_convert_required() - Query if HW param conversion was requested
* @data: Link data.
*
* Returns true if any HW param conversion was requested for this DAI link with
* any "convert-xxx" properties.
*/
bool asoc_simple_is_convert_required(const struct asoc_simple_data *data)
{
return data->convert_rate ||
data->convert_channels ||
data->convert_sample_format;
}
EXPORT_SYMBOL_GPL(asoc_simple_is_convert_required);
int asoc_simple_parse_daifmt(struct device *dev, int asoc_simple_parse_daifmt(struct device *dev,
struct device_node *node, struct device_node *node,
struct device_node *codec, struct device_node *codec,

View file

@ -393,8 +393,7 @@ static int __simple_for_each_link(struct asoc_simple_priv *priv,
* or has convert-xxx property * or has convert-xxx property
*/ */
if (dpcm_selectable && if (dpcm_selectable &&
(num > 2 || (num > 2 || asoc_simple_is_convert_required(&adata))) {
adata.convert_rate || adata.convert_channels)) {
/* /*
* np * np
* |1(CPU)|0(Codec) li->cpu * |1(CPU)|0(Codec) li->cpu

View file

@ -443,6 +443,13 @@ static const struct dmi_system_id byt_cht_es8316_quirk_table[] = {
| BYT_CHT_ES8316_INTMIC_IN2_MAP | BYT_CHT_ES8316_INTMIC_IN2_MAP
| BYT_CHT_ES8316_JD_INVERTED), | BYT_CHT_ES8316_JD_INVERTED),
}, },
{ /* Nanote UMPC-01 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"),
DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"),
},
.driver_data = (void *)BYT_CHT_ES8316_INTMIC_IN1_MAP,
},
{ /* Teclast X98 Plus II */ { /* Teclast X98 Plus II */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),

View file

@ -63,6 +63,7 @@ struct sof_es8336_private {
struct snd_soc_jack jack; struct snd_soc_jack jack;
struct list_head hdmi_pcm_list; struct list_head hdmi_pcm_list;
bool speaker_en; bool speaker_en;
struct delayed_work pcm_pop_work;
}; };
struct sof_hdmi_pcm { struct sof_hdmi_pcm {
@ -111,6 +112,46 @@ static void log_quirks(struct device *dev)
dev_info(dev, "quirk headset at mic1 port enabled\n"); dev_info(dev, "quirk headset at mic1 port enabled\n");
} }
static void pcm_pop_work_events(struct work_struct *work)
{
struct sof_es8336_private *priv =
container_of(work, struct sof_es8336_private, pcm_pop_work.work);
gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en);
if (quirk & SOF_ES8336_HEADPHONE_GPIO)
gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en);
}
static int sof_8336_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_card *card = rtd->card;
struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
case SNDRV_PCM_TRIGGER_RESUME:
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
if (priv->speaker_en == false)
if (substream->stream == 0) {
cancel_delayed_work(&priv->pcm_pop_work);
gpiod_set_value_cansleep(priv->gpio_speakers, true);
}
break;
default:
return -EINVAL;
}
return 0;
}
static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w, static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event) struct snd_kcontrol *kcontrol, int event)
{ {
@ -122,19 +163,7 @@ static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
priv->speaker_en = !SND_SOC_DAPM_EVENT_ON(event); priv->speaker_en = !SND_SOC_DAPM_EVENT_ON(event);
if (SND_SOC_DAPM_EVENT_ON(event)) queue_delayed_work(system_wq, &priv->pcm_pop_work, msecs_to_jiffies(70));
msleep(70);
gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en);
if (!(quirk & SOF_ES8336_HEADPHONE_GPIO))
return 0;
if (SND_SOC_DAPM_EVENT_ON(event))
msleep(70);
gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en);
return 0; return 0;
} }
@ -344,6 +373,7 @@ static int sof_es8336_hw_params(struct snd_pcm_substream *substream,
/* machine stream operations */ /* machine stream operations */
static struct snd_soc_ops sof_es8336_ops = { static struct snd_soc_ops sof_es8336_ops = {
.hw_params = sof_es8336_hw_params, .hw_params = sof_es8336_hw_params,
.trigger = sof_8336_trigger,
}; };
static struct snd_soc_dai_link_component platform_component[] = { static struct snd_soc_dai_link_component platform_component[] = {
@ -723,7 +753,8 @@ static int sof_es8336_probe(struct platform_device *pdev)
} }
INIT_LIST_HEAD(&priv->hdmi_pcm_list); INIT_LIST_HEAD(&priv->hdmi_pcm_list);
INIT_DELAYED_WORK(&priv->pcm_pop_work,
pcm_pop_work_events);
snd_soc_card_set_drvdata(card, priv); snd_soc_card_set_drvdata(card, priv);
if (mach->mach_params.dmic_num > 0) { if (mach->mach_params.dmic_num > 0) {
@ -752,6 +783,7 @@ static int sof_es8336_remove(struct platform_device *pdev)
struct snd_soc_card *card = platform_get_drvdata(pdev); struct snd_soc_card *card = platform_get_drvdata(pdev);
struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
cancel_delayed_work(&priv->pcm_pop_work);
gpiod_put(priv->gpio_speakers); gpiod_put(priv->gpio_speakers);
device_remove_software_node(priv->codec_dev); device_remove_software_node(priv->codec_dev);
put_device(priv->codec_dev); put_device(priv->codec_dev);

View file

@ -223,6 +223,18 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
SOF_RT5682_SSP_AMP(2) | SOF_RT5682_SSP_AMP(2) |
SOF_RT5682_NUM_HDMIDEV(4)), SOF_RT5682_NUM_HDMIDEV(4)),
}, },
{
.callback = sof_rt5682_quirk_cb,
.matches = {
DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"),
},
.driver_data = (void *)(SOF_RT5682_MCLK_EN |
SOF_RT5682_SSP_CODEC(2) |
SOF_SPEAKER_AMP_PRESENT |
SOF_RT5682_SSP_AMP(0) |
SOF_RT5682_NUM_HDMIDEV(4)
),
},
{} {}
}; };

View file

@ -202,6 +202,17 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
SOF_SDW_PCH_DMIC | SOF_SDW_PCH_DMIC |
RT711_JD1), RT711_JD1),
}, },
{
/* NUC15 LAPBC710 skews */
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
DMI_MATCH(DMI_BOARD_NAME, "LAPBC710"),
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
SOF_SDW_PCH_DMIC |
RT711_JD1),
},
/* TigerLake-SDCA devices */ /* TigerLake-SDCA devices */
{ {
.callback = sof_sdw_quirk_cb, .callback = sof_sdw_quirk_cb,

View file

@ -10,6 +10,11 @@
#include <sound/soc-acpi-intel-match.h> #include <sound/soc-acpi-intel-match.h>
#include "../skylake/skl.h" #include "../skylake/skl.h"
static const struct snd_soc_acpi_codecs essx_83x6 = {
.num_codecs = 3,
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
};
static struct skl_machine_pdata icl_pdata = { static struct skl_machine_pdata icl_pdata = {
.use_tplg_pcm = true, .use_tplg_pcm = true,
}; };
@ -27,6 +32,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_icl_machines[] = {
.drv_name = "sof_rt5682", .drv_name = "sof_rt5682",
.sof_tplg_filename = "sof-icl-rt5682.tplg", .sof_tplg_filename = "sof-icl-rt5682.tplg",
}, },
{
.comp_ids = &essx_83x6,
.drv_name = "sof-essx8336",
.sof_tplg_filename = "sof-icl-es8336", /* the tplg suffix is added at run time */
.tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
{}, {},
}; };
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines); EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_icl_machines);

View file

@ -689,11 +689,6 @@ static void load_codec_module(struct hda_codec *codec)
#endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */ #endif /* CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC */
static void skl_codec_device_exit(struct device *dev)
{
snd_hdac_device_exit(dev_to_hdac_dev(dev));
}
static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr) static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr)
{ {
struct hda_codec *codec; struct hda_codec *codec;
@ -706,12 +701,11 @@ static struct hda_codec *skl_codec_device_init(struct hdac_bus *bus, int addr)
} }
codec->core.type = HDA_DEV_ASOC; codec->core.type = HDA_DEV_ASOC;
codec->core.dev.release = skl_codec_device_exit;
ret = snd_hdac_device_register(&codec->core); ret = snd_hdac_device_register(&codec->core);
if (ret) { if (ret) {
dev_err(bus->dev, "failed to register hdac device\n"); dev_err(bus->dev, "failed to register hdac device\n");
snd_hdac_device_exit(&codec->core); put_device(&codec->core.dev);
return ERR_PTR(ret); return ERR_PTR(ret);
} }

View file

@ -187,6 +187,7 @@ config SND_SOC_SC8280XP
config SND_SOC_SC7180 config SND_SOC_SC7180
tristate "SoC Machine driver for SC7180 boards" tristate "SoC Machine driver for SC7180 boards"
depends on I2C && GPIOLIB depends on I2C && GPIOLIB
depends on SOUNDWIRE || SOUNDWIRE=n
select SND_SOC_QCOM_COMMON select SND_SOC_QCOM_COMMON
select SND_SOC_LPASS_SC7180 select SND_SOC_LPASS_SC7180
select SND_SOC_MAX98357A select SND_SOC_MAX98357A

View file

@ -782,10 +782,20 @@ static bool lpass_hdmi_regmap_volatile(struct device *dev, unsigned int reg)
return true; return true;
if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v)) if (reg == LPASS_HDMI_TX_LEGACY_ADDR(v))
return true; return true;
if (reg == LPASS_HDMI_TX_VBIT_CTL_ADDR(v))
return true;
if (reg == LPASS_HDMI_TX_PARITY_ADDR(v))
return true;
for (i = 0; i < v->hdmi_rdma_channels; ++i) { for (i = 0; i < v->hdmi_rdma_channels; ++i) {
if (reg == LPAIF_HDMI_RDMACURR_REG(v, i)) if (reg == LPAIF_HDMI_RDMACURR_REG(v, i))
return true; return true;
if (reg == LPASS_HDMI_TX_DMA_ADDR(v, i))
return true;
if (reg == LPASS_HDMI_TX_CH_LSB_ADDR(v, i))
return true;
if (reg == LPASS_HDMI_TX_CH_MSB_ADDR(v, i))
return true;
} }
return false; return false;
} }

View file

@ -1213,9 +1213,11 @@ int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd,
int i; int i;
for_each_rtd_components(rtd, i, component) { for_each_rtd_components(rtd, i, component) {
int ret = pm_runtime_resume_and_get(component->dev); int ret = pm_runtime_get_sync(component->dev);
if (ret < 0 && ret != -EACCES) if (ret < 0 && ret != -EACCES) {
pm_runtime_put_noidle(component->dev);
return soc_component_ret(component, ret); return soc_component_ret(component, ret);
}
/* mark stream if succeeded */ /* mark stream if succeeded */
soc_component_mark_push(component, stream, pm); soc_component_mark_push(component, stream, pm);
} }

View file

@ -3477,10 +3477,23 @@ EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_cpus);
static int __init snd_soc_init(void) static int __init snd_soc_init(void)
{ {
snd_soc_debugfs_init(); int ret;
snd_soc_util_init();
return platform_driver_register(&soc_driver); snd_soc_debugfs_init();
ret = snd_soc_util_init();
if (ret)
goto err_util_init;
ret = platform_driver_register(&soc_driver);
if (ret)
goto err_register;
return 0;
err_register:
snd_soc_util_exit();
err_util_init:
snd_soc_debugfs_exit();
return ret;
} }
module_init(snd_soc_init); module_init(snd_soc_init);

View file

@ -3645,7 +3645,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
switch (w->id) { switch (w->id) {
case snd_soc_dapm_regulator_supply: case snd_soc_dapm_regulator_supply:
w->regulator = devm_regulator_get(dapm->dev, w->name); w->regulator = devm_regulator_get(dapm->dev, widget->name);
if (IS_ERR(w->regulator)) { if (IS_ERR(w->regulator)) {
ret = PTR_ERR(w->regulator); ret = PTR_ERR(w->regulator);
goto request_failed; goto request_failed;

View file

@ -264,7 +264,7 @@ int __init snd_soc_util_init(void)
return ret; return ret;
} }
void __exit snd_soc_util_exit(void) void snd_soc_util_exit(void)
{ {
platform_driver_unregister(&soc_dummy_driver); platform_driver_unregister(&soc_dummy_driver);
platform_device_unregister(soc_dummy_dev); platform_device_unregister(soc_dummy_dev);

View file

@ -109,11 +109,6 @@ EXPORT_SYMBOL_NS(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC);
#define is_generic_config(x) 0 #define is_generic_config(x) 0
#endif #endif
static void hda_codec_device_exit(struct device *dev)
{
snd_hdac_device_exit(dev_to_hdac_dev(dev));
}
static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, int type) static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, int type)
{ {
struct hda_codec *codec; struct hda_codec *codec;
@ -126,12 +121,11 @@ static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, i
} }
codec->core.type = type; codec->core.type = type;
codec->core.dev.release = hda_codec_device_exit;
ret = snd_hdac_device_register(&codec->core); ret = snd_hdac_device_register(&codec->core);
if (ret) { if (ret) {
dev_err(bus->dev, "failed to register hdac device\n"); dev_err(bus->dev, "failed to register hdac device\n");
snd_hdac_device_exit(&codec->core); put_device(&codec->core.dev);
return ERR_PTR(ret); return ERR_PTR(ret);
} }

View file

@ -38,7 +38,7 @@ static const struct sof_dev_desc mtl_desc = {
[SOF_INTEL_IPC4] = "intel/sof-ace-tplg", [SOF_INTEL_IPC4] = "intel/sof-ace-tplg",
}, },
.default_fw_filename = { .default_fw_filename = {
[SOF_INTEL_IPC4] = "dsp_basefw.bin", [SOF_INTEL_IPC4] = "sof-mtl.ri",
}, },
.nocodec_tplg_filename = "sof-mtl-nocodec.tplg", .nocodec_tplg_filename = "sof-mtl-nocodec.tplg",
.ops = &sof_mtl_ops, .ops = &sof_mtl_ops,

View file

@ -159,6 +159,34 @@ static const struct sof_dev_desc adl_desc = {
.ops_init = sof_tgl_ops_init, .ops_init = sof_tgl_ops_init,
}; };
static const struct sof_dev_desc adl_n_desc = {
.machines = snd_soc_acpi_intel_adl_machines,
.alt_machines = snd_soc_acpi_intel_adl_sdw_machines,
.use_acpi_target_states = true,
.resindex_lpe_base = 0,
.resindex_pcicfg_base = -1,
.resindex_imr_base = -1,
.irqindex_host_ipc = -1,
.chip_info = &tgl_chip_info,
.ipc_supported_mask = BIT(SOF_IPC) | BIT(SOF_INTEL_IPC4),
.ipc_default = SOF_IPC,
.default_fw_path = {
[SOF_IPC] = "intel/sof",
[SOF_INTEL_IPC4] = "intel/avs/adl-n",
},
.default_tplg_path = {
[SOF_IPC] = "intel/sof-tplg",
[SOF_INTEL_IPC4] = "intel/avs-tplg",
},
.default_fw_filename = {
[SOF_IPC] = "sof-adl-n.ri",
[SOF_INTEL_IPC4] = "dsp_basefw.bin",
},
.nocodec_tplg_filename = "sof-adl-nocodec.tplg",
.ops = &sof_tgl_ops,
.ops_init = sof_tgl_ops_init,
};
static const struct sof_dev_desc rpls_desc = { static const struct sof_dev_desc rpls_desc = {
.machines = snd_soc_acpi_intel_rpl_machines, .machines = snd_soc_acpi_intel_rpl_machines,
.alt_machines = snd_soc_acpi_intel_rpl_sdw_machines, .alt_machines = snd_soc_acpi_intel_rpl_sdw_machines,
@ -246,7 +274,7 @@ static const struct pci_device_id sof_pci_ids[] = {
{ PCI_DEVICE(0x8086, 0x51cf), /* RPL-PX */ { PCI_DEVICE(0x8086, 0x51cf), /* RPL-PX */
.driver_data = (unsigned long)&rpl_desc}, .driver_data = (unsigned long)&rpl_desc},
{ PCI_DEVICE(0x8086, 0x54c8), /* ADL-N */ { PCI_DEVICE(0x8086, 0x54c8), /* ADL-N */
.driver_data = (unsigned long)&adl_desc}, .driver_data = (unsigned long)&adl_n_desc},
{ 0, } { 0, }
}; };
MODULE_DEVICE_TABLE(pci, sof_pci_ids); MODULE_DEVICE_TABLE(pci, sof_pci_ids);

View file

@ -2275,6 +2275,7 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
struct sof_ipc_fw_version *v = &sdev->fw_ready.version; struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
struct snd_sof_widget *swidget; struct snd_sof_widget *swidget;
struct snd_sof_route *sroute; struct snd_sof_route *sroute;
bool dyn_widgets = false;
int ret; int ret;
/* /*
@ -2284,12 +2285,14 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
* topology loading the sound card unavailable to open PCMs. * topology loading the sound card unavailable to open PCMs.
*/ */
list_for_each_entry(swidget, &sdev->widget_list, list) { list_for_each_entry(swidget, &sdev->widget_list, list) {
if (swidget->dynamic_pipeline_widget) if (swidget->dynamic_pipeline_widget) {
dyn_widgets = true;
continue; continue;
}
/* Do not free widgets for static pipelines with FW ABI older than 3.19 */ /* Do not free widgets for static pipelines with FW older than SOF2.2 */
if (!verify && !swidget->dynamic_pipeline_widget && if (!verify && !swidget->dynamic_pipeline_widget &&
v->abi_version < SOF_ABI_VER(3, 19, 0)) { SOF_FW_VER(v->major, v->minor, v->micro) < SOF_FW_VER(2, 2, 0)) {
swidget->use_count = 0; swidget->use_count = 0;
swidget->complete = 0; swidget->complete = 0;
continue; continue;
@ -2303,9 +2306,11 @@ static int sof_ipc3_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
/* /*
* Tear down all pipelines associated with PCMs that did not get suspended * Tear down all pipelines associated with PCMs that did not get suspended
* and unset the prepare flag so that they can be set up again during resume. * and unset the prepare flag so that they can be set up again during resume.
* Skip this step for older firmware. * Skip this step for older firmware unless topology has any
* dynamic pipeline (in which case the step is mandatory).
*/ */
if (!verify && v->abi_version >= SOF_ABI_VER(3, 19, 0)) { if (!verify && (dyn_widgets || SOF_FW_VER(v->major, v->minor, v->micro) >=
SOF_FW_VER(2, 2, 0))) {
ret = sof_tear_down_left_over_pipelines(sdev); ret = sof_tear_down_left_over_pipelines(sdev);
if (ret < 0) { if (ret < 0) {
dev_err(sdev->dev, "failed to tear down paused pipelines\n"); dev_err(sdev->dev, "failed to tear down paused pipelines\n");

View file

@ -108,6 +108,7 @@ struct sof_mtrace_core_data {
int id; int id;
u32 slot_offset; u32 slot_offset;
void *log_buffer; void *log_buffer;
struct mutex buffer_lock; /* for log_buffer alloc/free */
u32 host_read_ptr; u32 host_read_ptr;
u32 dsp_write_ptr; u32 dsp_write_ptr;
/* pos update IPC arrived before the slot offset is known, queried */ /* pos update IPC arrived before the slot offset is known, queried */
@ -128,14 +129,22 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file)
struct sof_mtrace_core_data *core_data = inode->i_private; struct sof_mtrace_core_data *core_data = inode->i_private;
int ret; int ret;
mutex_lock(&core_data->buffer_lock);
if (core_data->log_buffer) {
ret = -EBUSY;
goto out;
}
ret = debugfs_file_get(file->f_path.dentry); ret = debugfs_file_get(file->f_path.dentry);
if (unlikely(ret)) if (unlikely(ret))
return ret; goto out;
core_data->log_buffer = kmalloc(SOF_MTRACE_SLOT_SIZE, GFP_KERNEL); core_data->log_buffer = kmalloc(SOF_MTRACE_SLOT_SIZE, GFP_KERNEL);
if (!core_data->log_buffer) { if (!core_data->log_buffer) {
debugfs_file_put(file->f_path.dentry); debugfs_file_put(file->f_path.dentry);
return -ENOMEM; ret = -ENOMEM;
goto out;
} }
ret = simple_open(inode, file); ret = simple_open(inode, file);
@ -144,6 +153,9 @@ static int sof_ipc4_mtrace_dfs_open(struct inode *inode, struct file *file)
debugfs_file_put(file->f_path.dentry); debugfs_file_put(file->f_path.dentry);
} }
out:
mutex_unlock(&core_data->buffer_lock);
return ret; return ret;
} }
@ -280,7 +292,10 @@ static int sof_ipc4_mtrace_dfs_release(struct inode *inode, struct file *file)
debugfs_file_put(file->f_path.dentry); debugfs_file_put(file->f_path.dentry);
mutex_lock(&core_data->buffer_lock);
kfree(core_data->log_buffer); kfree(core_data->log_buffer);
core_data->log_buffer = NULL;
mutex_unlock(&core_data->buffer_lock);
return 0; return 0;
} }
@ -563,6 +578,7 @@ static int ipc4_mtrace_init(struct snd_sof_dev *sdev)
struct sof_mtrace_core_data *core_data = &priv->cores[i]; struct sof_mtrace_core_data *core_data = &priv->cores[i];
init_waitqueue_head(&core_data->trace_sleep); init_waitqueue_head(&core_data->trace_sleep);
mutex_init(&core_data->buffer_lock);
core_data->sdev = sdev; core_data->sdev = sdev;
core_data->id = i; core_data->id = i;
} }

View file

@ -1344,16 +1344,6 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
break; break;
} }
if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
swidget->core = SOF_DSP_PRIMARY_CORE;
} else {
int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples,
swidget->num_tuples);
if (core >= 0)
swidget->core = core;
}
/* check token parsing reply */ /* check token parsing reply */
if (ret < 0) { if (ret < 0) {
dev_err(scomp->dev, dev_err(scomp->dev,
@ -1365,6 +1355,16 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
return ret; return ret;
} }
if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
swidget->core = SOF_DSP_PRIMARY_CORE;
} else {
int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples,
swidget->num_tuples);
if (core >= 0)
swidget->core = core;
}
/* bind widget to external event */ /* bind widget to external event */
if (tw->event_type) { if (tw->event_type) {
if (widget_ops[w->id].bind_event) { if (widget_ops[w->id].bind_event) {

View file

@ -304,6 +304,11 @@ static int stm32_adfsdm_dummy_cb(const void *data, void *private)
return 0; return 0;
} }
static void stm32_adfsdm_cleanup(void *data)
{
iio_channel_release_all_cb(data);
}
static struct snd_soc_component_driver stm32_adfsdm_soc_platform = { static struct snd_soc_component_driver stm32_adfsdm_soc_platform = {
.open = stm32_adfsdm_pcm_open, .open = stm32_adfsdm_pcm_open,
.close = stm32_adfsdm_pcm_close, .close = stm32_adfsdm_pcm_close,
@ -350,6 +355,12 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
if (IS_ERR(priv->iio_cb)) if (IS_ERR(priv->iio_cb))
return PTR_ERR(priv->iio_cb); return PTR_ERR(priv->iio_cb);
ret = devm_add_action_or_reset(&pdev->dev, stm32_adfsdm_cleanup, priv->iio_cb);
if (ret < 0) {
dev_err(&pdev->dev, "Unable to add action\n");
return ret;
}
component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL); component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL);
if (!component) if (!component)
return -ENOMEM; return -ENOMEM;

View file

@ -126,15 +126,10 @@ EXPORT_SYMBOL(snd_emux_register);
*/ */
int snd_emux_free(struct snd_emux *emu) int snd_emux_free(struct snd_emux *emu)
{ {
unsigned long flags;
if (! emu) if (! emu)
return -EINVAL; return -EINVAL;
spin_lock_irqsave(&emu->voice_lock, flags); del_timer_sync(&emu->tlist);
if (emu->timer_active)
del_timer(&emu->tlist);
spin_unlock_irqrestore(&emu->voice_lock, flags);
snd_emux_proc_free(emu); snd_emux_proc_free(emu);
snd_emux_delete_virmidi(emu); snd_emux_delete_virmidi(emu);

View file

@ -742,6 +742,18 @@ get_alias_quirk(struct usb_device *dev, unsigned int id)
return NULL; return NULL;
} }
/* register card if we reach to the last interface or to the specified
* one given via option
*/
static int try_to_register_card(struct snd_usb_audio *chip, int ifnum)
{
if (check_delayed_register_option(chip) == ifnum ||
chip->last_iface == ifnum ||
usb_interface_claimed(usb_ifnum_to_if(chip->dev, chip->last_iface)))
return snd_card_register(chip->card);
return 0;
}
/* /*
* probe the active usb device * probe the active usb device
* *
@ -880,15 +892,9 @@ static int usb_audio_probe(struct usb_interface *intf,
chip->need_delayed_register = false; /* clear again */ chip->need_delayed_register = false; /* clear again */
} }
/* register card if we reach to the last interface or to the specified err = try_to_register_card(chip, ifnum);
* one given via option if (err < 0)
*/ goto __error_no_register;
if (check_delayed_register_option(chip) == ifnum ||
usb_interface_claimed(usb_ifnum_to_if(dev, chip->last_iface))) {
err = snd_card_register(chip->card);
if (err < 0)
goto __error;
}
if (chip->quirk_flags & QUIRK_FLAG_SHARE_MEDIA_DEVICE) { if (chip->quirk_flags & QUIRK_FLAG_SHARE_MEDIA_DEVICE) {
/* don't want to fail when snd_media_device_create() fails */ /* don't want to fail when snd_media_device_create() fails */
@ -907,6 +913,11 @@ static int usb_audio_probe(struct usb_interface *intf,
return 0; return 0;
__error: __error:
/* in the case of error in secondary interface, still try to register */
if (chip)
try_to_register_card(chip, ifnum);
__error_no_register:
if (chip) { if (chip) {
/* chip->active is inside the chip->card object, /* chip->active is inside the chip->card object,
* decrement before memory is possibly returned. * decrement before memory is possibly returned.

View file

@ -931,7 +931,8 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip,
usb_audio_dbg(chip, "Closing EP 0x%x (count %d)\n", usb_audio_dbg(chip, "Closing EP 0x%x (count %d)\n",
ep->ep_num, ep->opened); ep->ep_num, ep->opened);
if (!--ep->iface_ref->opened) if (!--ep->iface_ref->opened &&
!(chip->quirk_flags & QUIRK_FLAG_IFACE_SKIP_CLOSE))
endpoint_set_interface(chip, ep, false); endpoint_set_interface(chip, ep, false);
if (!--ep->opened) { if (!--ep->opened) {

View file

@ -47,6 +47,8 @@ struct snd_usb_implicit_fb_match {
static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = { static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
/* Fixed EP */ /* Fixed EP */
/* FIXME: check the availability of generic matching */ /* FIXME: check the availability of generic matching */
IMPLICIT_FB_FIXED_DEV(0x0763, 0x2030, 0x81, 3), /* M-Audio Fast Track C400 */
IMPLICIT_FB_FIXED_DEV(0x0763, 0x2031, 0x81, 3), /* M-Audio Fast Track C600 */
IMPLICIT_FB_FIXED_DEV(0x0763, 0x2080, 0x81, 2), /* M-Audio FastTrack Ultra */ IMPLICIT_FB_FIXED_DEV(0x0763, 0x2080, 0x81, 2), /* M-Audio FastTrack Ultra */
IMPLICIT_FB_FIXED_DEV(0x0763, 0x2081, 0x81, 2), /* M-Audio FastTrack Ultra */ IMPLICIT_FB_FIXED_DEV(0x0763, 0x2081, 0x81, 2), /* M-Audio FastTrack Ultra */
IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */ IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */

View file

@ -1133,10 +1133,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
port = &umidi->endpoints[i].out->ports[j]; port = &umidi->endpoints[i].out->ports[j];
break; break;
} }
if (!port) { if (!port)
snd_BUG();
return -ENXIO; return -ENXIO;
}
substream->runtime->private_data = port; substream->runtime->private_data = port;
port->state = STATE_UNKNOWN; port->state = STATE_UNKNOWN;

View file

@ -1631,7 +1631,7 @@ static void check_no_speaker_on_headset(struct snd_kcontrol *kctl,
if (!found) if (!found)
return; return;
strscpy(kctl->id.name, "Headphone", sizeof(kctl->id.name)); snd_ctl_rename(card, kctl, "Headphone");
} }
static const struct usb_feature_control_info *get_feature_control_info(int control) static const struct usb_feature_control_info *get_feature_control_info(int control)

View file

@ -2049,6 +2049,10 @@ YAMAHA_DEVICE(0x7010, "UB99"),
} }
} }
}, },
{
/* M-Audio Micro */
USB_DEVICE_VENDOR_SPEC(0x0763, 0x201a),
},
{ {
USB_DEVICE_VENDOR_SPEC(0x0763, 0x2030), USB_DEVICE_VENDOR_SPEC(0x0763, 0x2030),
.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {

View file

@ -376,7 +376,8 @@ static int create_auto_midi_quirk(struct snd_usb_audio *chip,
static int create_autodetect_quirk(struct snd_usb_audio *chip, static int create_autodetect_quirk(struct snd_usb_audio *chip,
struct usb_interface *iface, struct usb_interface *iface,
struct usb_driver *driver) struct usb_driver *driver,
const struct snd_usb_audio_quirk *quirk)
{ {
int err; int err;
@ -386,45 +387,6 @@ static int create_autodetect_quirk(struct snd_usb_audio *chip,
return err; return err;
} }
static int create_autodetect_quirks(struct snd_usb_audio *chip,
struct usb_interface *iface,
struct usb_driver *driver,
const struct snd_usb_audio_quirk *quirk)
{
int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
int ifcount, ifnum, err;
err = create_autodetect_quirk(chip, iface, driver);
if (err < 0)
return err;
/*
* ALSA PCM playback/capture devices cannot be registered in two steps,
* so we have to claim the other corresponding interface here.
*/
ifcount = chip->dev->actconfig->desc.bNumInterfaces;
for (ifnum = 0; ifnum < ifcount; ifnum++) {
if (ifnum == probed_ifnum || quirk->ifnum >= 0)
continue;
iface = usb_ifnum_to_if(chip->dev, ifnum);
if (!iface ||
usb_interface_claimed(iface) ||
get_iface_desc(iface->altsetting)->bInterfaceClass !=
USB_CLASS_VENDOR_SPEC)
continue;
err = create_autodetect_quirk(chip, iface, driver);
if (err >= 0) {
err = usb_driver_claim_interface(driver, iface,
USB_AUDIO_IFACE_UNUSED);
if (err < 0)
return err;
}
}
return 0;
}
/* /*
* Create a stream for an Edirol UA-700/UA-25/UA-4FX interface. * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
* The only way to detect the sample rate is by looking at wMaxPacketSize. * The only way to detect the sample rate is by looking at wMaxPacketSize.
@ -554,7 +516,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
static const quirk_func_t quirk_funcs[] = { static const quirk_func_t quirk_funcs[] = {
[QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk, [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
[QUIRK_COMPOSITE] = create_composite_quirk, [QUIRK_COMPOSITE] = create_composite_quirk,
[QUIRK_AUTODETECT] = create_autodetect_quirks, [QUIRK_AUTODETECT] = create_autodetect_quirk,
[QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk, [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
[QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk, [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
[QUIRK_MIDI_YAMAHA] = create_any_midi_quirk, [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
@ -1913,6 +1875,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
/* XMOS based USB DACs */ /* XMOS based USB DACs */
switch (chip->usb_id) { switch (chip->usb_id) {
case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */ case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */
case USB_ID(0x21ed, 0xd75a): /* Accuphase DAC-60 option card */
case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */ case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */
case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
if (fp->altsetting == 2) if (fp->altsetting == 2)
@ -2185,6 +2148,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_GENERIC_IMPLICIT_FB), QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */ DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */
QUIRK_FLAG_GENERIC_IMPLICIT_FB), QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */
QUIRK_FLAG_IFACE_SKIP_CLOSE),
/* Vendor matches */ /* Vendor matches */
VENDOR_FLG(0x045e, /* MS Lifecam */ VENDOR_FLG(0x045e, /* MS Lifecam */

View file

@ -170,6 +170,8 @@ extern bool snd_usb_skip_validation;
* Apply the generic implicit feedback sync mode (same as implicit_fb=1 option) * Apply the generic implicit feedback sync mode (same as implicit_fb=1 option)
* QUIRK_FLAG_SKIP_IMPLICIT_FB * QUIRK_FLAG_SKIP_IMPLICIT_FB
* Don't apply implicit feedback sync mode * Don't apply implicit feedback sync mode
* QUIRK_FLAG_IFACE_SKIP_CLOSE
* Don't closed interface during setting sample rate
*/ */
#define QUIRK_FLAG_GET_SAMPLE_RATE (1U << 0) #define QUIRK_FLAG_GET_SAMPLE_RATE (1U << 0)
@ -191,5 +193,6 @@ extern bool snd_usb_skip_validation;
#define QUIRK_FLAG_SET_IFACE_FIRST (1U << 16) #define QUIRK_FLAG_SET_IFACE_FIRST (1U << 16)
#define QUIRK_FLAG_GENERIC_IMPLICIT_FB (1U << 17) #define QUIRK_FLAG_GENERIC_IMPLICIT_FB (1U << 17)
#define QUIRK_FLAG_SKIP_IMPLICIT_FB (1U << 18) #define QUIRK_FLAG_SKIP_IMPLICIT_FB (1U << 18)
#define QUIRK_FLAG_IFACE_SKIP_CLOSE (1U << 19)
#endif /* __USBAUDIO_H */ #endif /* __USBAUDIO_H */