Commit ce18d3aa authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-6.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "A bit higher volume of changes than wished, but each change is
  relatively small and the fix targets are mostly device-specific, so
  those should be safe as a late stage merge.

  The most significant LoC is about the memalloc helper fix, which is
  applied only to Xen PV. The other major parts are ASoC Intel SOF and
  AVS fixes that are scattered as various small code changes. The rest
  are device-specific fixes and quirks for HD- and USB-audio, FireWire
  and ASoC AMD / HDMI"

* tag 'sound-6.2-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (30 commits)
  ALSA: firewire-motu: fix unreleased lock warning in hwdep device
  ALSA: memalloc: Workaround for Xen PV
  ASoC: cs42l56: fix DT probe
  ASoC: codecs: wsa883x: correct playback min/max rates
  ALSA: hda/realtek: Add Acer Predator PH315-54
  ASoC: amd: yc: Add Xiaomi Redmi Book Pro 15 2022 into DMI table
  ALSA: hda: Do not unset preset when cleaning up codec
  ASoC: SOF: sof-audio: prepare_widgets: Check swidget for NULL on sink failure
  ASoC: hdmi-codec: zero clear HDMI pdata
  ASoC: SOF: ipc4-mtrace: prevent underflow in sof_ipc4_priority_mask_dfs_write()
  ASoC: Intel: sof_ssp_amp: always set dpcm_capture for amplifiers
  ASoC: Intel: sof_nau8825: always set dpcm_capture for amplifiers
  ASoC: Intel: sof_cs42l42: always set dpcm_capture for amplifiers
  ASoC: Intel: sof_rt5682: always set dpcm_capture for amplifiers
  ALSA: hda/via: Avoid potential array out-of-bound in add_secret_dac_path()
  ALSA: usb-audio: Add FIXED_RATE quirk for JBL Quantum610 Wireless
  ALSA: hda/realtek: fix mute/micmute LEDs, speaker don't work for a HP platform
  ASoC: SOF: keep prepare/unprepare widgets in sink path
  ASoC: SOF: sof-audio: skip prepare/unprepare if swidget is NULL
  ASoC: SOF: sof-audio: unprepare when swidget->use_count > 0
  ...
parents c0b67534 c7a806d9
...@@ -819,8 +819,10 @@ static int ioctl_send_response(struct client *client, union ioctl_arg *arg) ...@@ -819,8 +819,10 @@ static int ioctl_send_response(struct client *client, union ioctl_arg *arg)
r = container_of(resource, struct inbound_transaction_resource, r = container_of(resource, struct inbound_transaction_resource,
resource); resource);
if (is_fcp_request(r->request)) if (is_fcp_request(r->request)) {
kfree(r->data);
goto out; goto out;
}
if (a->length != fw_get_response_length(r->request)) { if (a->length != fw_get_response_length(r->request)) {
ret = -EINVAL; ret = -EINVAL;
......
...@@ -193,6 +193,7 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev) ...@@ -193,6 +193,7 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
struct hdmi_codec_pdata pdata; struct hdmi_codec_pdata pdata;
struct platform_device *platform; struct platform_device *platform;
memset(&pdata, 0, sizeof(pdata));
pdata.ops = &dw_hdmi_i2s_ops; pdata.ops = &dw_hdmi_i2s_ops;
pdata.i2s = 1; pdata.i2s = 1;
pdata.max_i2s_channels = 8; pdata.max_i2s_channels = 8;
......
...@@ -541,16 +541,15 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size) ...@@ -541,16 +541,15 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size)
struct sg_table *sgt; struct sg_table *sgt;
void *p; void *p;
#ifdef CONFIG_SND_DMA_SGBUF
if (cpu_feature_enabled(X86_FEATURE_XENPV))
return snd_dma_sg_fallback_alloc(dmab, size);
#endif
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);
#ifdef CONFIG_SND_DMA_SGBUF #ifdef CONFIG_SND_DMA_SGBUF
if (!sgt && !get_dma_ops(dmab->dev.dev)) { if (!sgt && !get_dma_ops(dmab->dev.dev))
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG)
dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK;
else
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);
}
#endif #endif
if (!sgt) if (!sgt)
return NULL; return NULL;
...@@ -717,19 +716,38 @@ static const struct snd_malloc_ops snd_dma_sg_wc_ops = { ...@@ -717,19 +716,38 @@ static const struct snd_malloc_ops snd_dma_sg_wc_ops = {
/* Fallback SG-buffer allocations for x86 */ /* Fallback SG-buffer allocations for x86 */
struct snd_dma_sg_fallback { struct snd_dma_sg_fallback {
bool use_dma_alloc_coherent;
size_t count; size_t count;
struct page **pages; struct page **pages;
/* DMA address array; the first page contains #pages in ~PAGE_MASK */
dma_addr_t *addrs;
}; };
static void __snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab, static void __snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab,
struct snd_dma_sg_fallback *sgbuf) struct snd_dma_sg_fallback *sgbuf)
{ {
bool wc = dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; size_t i, size;
size_t i;
if (sgbuf->pages && sgbuf->addrs) {
for (i = 0; i < sgbuf->count && sgbuf->pages[i]; i++) i = 0;
do_free_pages(page_address(sgbuf->pages[i]), PAGE_SIZE, wc); while (i < sgbuf->count) {
if (!sgbuf->pages[i] || !sgbuf->addrs[i])
break;
size = sgbuf->addrs[i] & ~PAGE_MASK;
if (WARN_ON(!size))
break;
if (sgbuf->use_dma_alloc_coherent)
dma_free_coherent(dmab->dev.dev, size << PAGE_SHIFT,
page_address(sgbuf->pages[i]),
sgbuf->addrs[i] & PAGE_MASK);
else
do_free_pages(page_address(sgbuf->pages[i]),
size << PAGE_SHIFT, false);
i += size;
}
}
kvfree(sgbuf->pages); kvfree(sgbuf->pages);
kvfree(sgbuf->addrs);
kfree(sgbuf); kfree(sgbuf);
} }
...@@ -738,24 +756,36 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size) ...@@ -738,24 +756,36 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size)
struct snd_dma_sg_fallback *sgbuf; struct snd_dma_sg_fallback *sgbuf;
struct page **pagep, *curp; struct page **pagep, *curp;
size_t chunk, npages; size_t chunk, npages;
dma_addr_t *addrp;
dma_addr_t addr; dma_addr_t addr;
void *p; void *p;
bool wc = dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK;
/* correct the type */
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG)
dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK;
else if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG)
dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK;
sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL); sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL);
if (!sgbuf) if (!sgbuf)
return NULL; return NULL;
sgbuf->use_dma_alloc_coherent = cpu_feature_enabled(X86_FEATURE_XENPV);
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);
sgbuf->count = size >> PAGE_SHIFT; sgbuf->count = size >> PAGE_SHIFT;
sgbuf->pages = kvcalloc(sgbuf->count, sizeof(*sgbuf->pages), GFP_KERNEL); sgbuf->pages = kvcalloc(sgbuf->count, sizeof(*sgbuf->pages), GFP_KERNEL);
if (!sgbuf->pages) sgbuf->addrs = kvcalloc(sgbuf->count, sizeof(*sgbuf->addrs), GFP_KERNEL);
if (!sgbuf->pages || !sgbuf->addrs)
goto error; goto error;
pagep = sgbuf->pages; pagep = sgbuf->pages;
chunk = size; addrp = sgbuf->addrs;
chunk = (PAGE_SIZE - 1) << PAGE_SHIFT; /* to fit in low bits in addrs */
while (size > 0) { while (size > 0) {
chunk = min(size, chunk); chunk = min(size, chunk);
p = do_alloc_pages(dmab->dev.dev, chunk, &addr, wc); if (sgbuf->use_dma_alloc_coherent)
p = dma_alloc_coherent(dmab->dev.dev, chunk, &addr, DEFAULT_GFP);
else
p = do_alloc_pages(dmab->dev.dev, chunk, &addr, false);
if (!p) { if (!p) {
if (chunk <= PAGE_SIZE) if (chunk <= PAGE_SIZE)
goto error; goto error;
...@@ -767,17 +797,25 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size) ...@@ -767,17 +797,25 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size)
size -= chunk; size -= chunk;
/* fill pages */ /* fill pages */
npages = chunk >> PAGE_SHIFT; npages = chunk >> PAGE_SHIFT;
*addrp = npages; /* store in lower bits */
curp = virt_to_page(p); curp = virt_to_page(p);
while (npages--) while (npages--) {
*pagep++ = curp++; *pagep++ = curp++;
*addrp++ |= addr;
addr += PAGE_SIZE;
}
} }
p = vmap(sgbuf->pages, sgbuf->count, VM_MAP, PAGE_KERNEL); p = vmap(sgbuf->pages, sgbuf->count, VM_MAP, PAGE_KERNEL);
if (!p) if (!p)
goto error; goto error;
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK)
set_pages_array_wc(sgbuf->pages, sgbuf->count);
dmab->private_data = sgbuf; dmab->private_data = sgbuf;
/* store the first page address for convenience */ /* store the first page address for convenience */
dmab->addr = snd_sgbuf_get_addr(dmab, 0); dmab->addr = sgbuf->addrs[0] & PAGE_MASK;
return p; return p;
error: error:
...@@ -787,10 +825,23 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size) ...@@ -787,10 +825,23 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size)
static void snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab) static void snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab)
{ {
struct snd_dma_sg_fallback *sgbuf = dmab->private_data;
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK)
set_pages_array_wb(sgbuf->pages, sgbuf->count);
vunmap(dmab->area); vunmap(dmab->area);
__snd_dma_sg_fallback_free(dmab, dmab->private_data); __snd_dma_sg_fallback_free(dmab, dmab->private_data);
} }
static dma_addr_t snd_dma_sg_fallback_get_addr(struct snd_dma_buffer *dmab,
size_t offset)
{
struct snd_dma_sg_fallback *sgbuf = dmab->private_data;
size_t index = offset >> PAGE_SHIFT;
return (sgbuf->addrs[index] & PAGE_MASK) | (offset & ~PAGE_MASK);
}
static int snd_dma_sg_fallback_mmap(struct snd_dma_buffer *dmab, static int snd_dma_sg_fallback_mmap(struct snd_dma_buffer *dmab,
struct vm_area_struct *area) struct vm_area_struct *area)
{ {
...@@ -805,8 +856,8 @@ static const struct snd_malloc_ops snd_dma_sg_fallback_ops = { ...@@ -805,8 +856,8 @@ static const struct snd_malloc_ops snd_dma_sg_fallback_ops = {
.alloc = snd_dma_sg_fallback_alloc, .alloc = snd_dma_sg_fallback_alloc,
.free = snd_dma_sg_fallback_free, .free = snd_dma_sg_fallback_free,
.mmap = snd_dma_sg_fallback_mmap, .mmap = snd_dma_sg_fallback_mmap,
.get_addr = snd_dma_sg_fallback_get_addr,
/* reuse vmalloc helpers */ /* reuse vmalloc helpers */
.get_addr = snd_dma_vmalloc_get_addr,
.get_page = snd_dma_vmalloc_get_page, .get_page = snd_dma_vmalloc_get_page,
.get_chunk_size = snd_dma_vmalloc_get_chunk_size, .get_chunk_size = snd_dma_vmalloc_get_chunk_size,
}; };
......
...@@ -87,6 +87,10 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, ...@@ -87,6 +87,10 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
return -EFAULT; return -EFAULT;
count = consumed; count = consumed;
} else {
spin_unlock_irq(&motu->lock);
count = 0;
} }
return count; return count;
......
...@@ -144,6 +144,7 @@ static int hda_codec_driver_probe(struct device *dev) ...@@ -144,6 +144,7 @@ static int hda_codec_driver_probe(struct device *dev)
error: error:
snd_hda_codec_cleanup_for_unbind(codec); snd_hda_codec_cleanup_for_unbind(codec);
codec->preset = NULL;
return err; return err;
} }
...@@ -166,6 +167,7 @@ static int hda_codec_driver_remove(struct device *dev) ...@@ -166,6 +167,7 @@ static int hda_codec_driver_remove(struct device *dev)
if (codec->patch_ops.free) if (codec->patch_ops.free)
codec->patch_ops.free(codec); codec->patch_ops.free(codec);
snd_hda_codec_cleanup_for_unbind(codec); snd_hda_codec_cleanup_for_unbind(codec);
codec->preset = NULL;
module_put(dev->driver->owner); module_put(dev->driver->owner);
return 0; return 0;
} }
......
...@@ -795,7 +795,6 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec) ...@@ -795,7 +795,6 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
snd_array_free(&codec->cvt_setups); snd_array_free(&codec->cvt_setups);
snd_array_free(&codec->spdif_out); snd_array_free(&codec->spdif_out);
snd_array_free(&codec->verbs); snd_array_free(&codec->verbs);
codec->preset = NULL;
codec->follower_dig_outs = NULL; codec->follower_dig_outs = NULL;
codec->spdif_status_reset = 0; codec->spdif_status_reset = 0;
snd_array_free(&codec->mixers); snd_array_free(&codec->mixers);
......
...@@ -9202,6 +9202,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -9202,6 +9202,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x142b, "Acer Swift SF314-42", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x142b, "Acer Swift SF314-42", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC), SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC),
SND_PCI_QUIRK(0x1025, 0x1534, "Acer Predator PH315-54", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
SND_PCI_QUIRK(0x1028, 0x053c, "Dell Latitude E5430", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x053c, "Dell Latitude E5430", ALC292_FIXUP_DELL_E7X),
SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS),
...@@ -9432,6 +9433,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { ...@@ -9432,6 +9433,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
......
...@@ -819,6 +819,9 @@ static int add_secret_dac_path(struct hda_codec *codec) ...@@ -819,6 +819,9 @@ static int add_secret_dac_path(struct hda_codec *codec)
return 0; return 0;
nums = snd_hda_get_connections(codec, spec->gen.mixer_nid, conn, nums = snd_hda_get_connections(codec, spec->gen.mixer_nid, conn,
ARRAY_SIZE(conn) - 1); ARRAY_SIZE(conn) - 1);
if (nums < 0)
return nums;
for (i = 0; i < nums; i++) { for (i = 0; i < nums; i++) {
if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT) if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT)
return 0; return 0;
......
...@@ -198,9 +198,11 @@ static int st_es8336_late_probe(struct snd_soc_card *card) ...@@ -198,9 +198,11 @@ static int st_es8336_late_probe(struct snd_soc_card *card)
int ret; int ret;
adev = acpi_dev_get_first_match_dev("ESSX8336", NULL, -1); adev = acpi_dev_get_first_match_dev("ESSX8336", NULL, -1);
if (adev) if (!adev)
put_device(&adev->dev); return -ENODEV;
codec_dev = acpi_get_first_physical_node(adev); codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);
if (!codec_dev) if (!codec_dev)
dev_err(card->dev, "can not find codec dev\n"); dev_err(card->dev, "can not find codec dev\n");
......
...@@ -227,6 +227,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { ...@@ -227,6 +227,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"), DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"),
} }
}, },
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"),
DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 15 2022"),
}
},
{ {
.driver_data = &acp6x_card, .driver_data = &acp6x_card,
.matches = { .matches = {
...@@ -234,6 +241,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { ...@@ -234,6 +241,20 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Blade 14 (2022) - RZ09-0427"), DMI_MATCH(DMI_PRODUCT_NAME, "Blade 14 (2022) - RZ09-0427"),
} }
}, },
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "RB"),
DMI_MATCH(DMI_PRODUCT_NAME, "Swift SFA16-41"),
}
},
{
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "IRBIS"),
DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"),
}
},
{} {}
}; };
......
...@@ -1191,18 +1191,12 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client) ...@@ -1191,18 +1191,12 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client)
if (pdata) { if (pdata) {
cs42l56->pdata = *pdata; cs42l56->pdata = *pdata;
} else { } else {
pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),
GFP_KERNEL);
if (!pdata)
return -ENOMEM;
if (i2c_client->dev.of_node) { if (i2c_client->dev.of_node) {
ret = cs42l56_handle_of_data(i2c_client, ret = cs42l56_handle_of_data(i2c_client,
&cs42l56->pdata); &cs42l56->pdata);
if (ret != 0) if (ret != 0)
return ret; return ret;
} }
cs42l56->pdata = *pdata;
} }
if (cs42l56->pdata.gpio_nreset) { if (cs42l56->pdata.gpio_nreset) {
......
...@@ -1359,8 +1359,8 @@ static struct snd_soc_dai_driver wsa883x_dais[] = { ...@@ -1359,8 +1359,8 @@ static struct snd_soc_dai_driver wsa883x_dais[] = {
.stream_name = "SPKR Playback", .stream_name = "SPKR Playback",
.rates = WSA883X_RATES | WSA883X_FRAC_RATES, .rates = WSA883X_RATES | WSA883X_FRAC_RATES,
.formats = WSA883X_FORMATS, .formats = WSA883X_FORMATS,
.rate_max = 8000, .rate_min = 8000,
.rate_min = 352800, .rate_max = 352800,
.channels_min = 1, .channels_min = 1,
.channels_max = 1, .channels_max = 1,
}, },
......
...@@ -481,6 +481,29 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) ...@@ -481,6 +481,29 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
return ret; return ret;
} }
static void avs_pci_shutdown(struct pci_dev *pci)
{
struct hdac_bus *bus = pci_get_drvdata(pci);
struct avs_dev *adev = hdac_to_avs(bus);
cancel_work_sync(&adev->probe_work);
avs_ipc_block(adev->ipc);
snd_hdac_stop_streams(bus);
avs_dsp_op(adev, int_control, false);
snd_hdac_ext_bus_ppcap_int_enable(bus, false);
snd_hdac_ext_bus_link_power_down_all(bus);
snd_hdac_bus_stop_chip(bus);
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
if (avs_platattr_test(adev, CLDMA))
pci_free_irq(pci, 0, &code_loader);
pci_free_irq(pci, 0, adev);
pci_free_irq(pci, 0, bus);
pci_free_irq_vectors(pci);
}
static void avs_pci_remove(struct pci_dev *pci) static void avs_pci_remove(struct pci_dev *pci)
{ {
struct hdac_device *hdev, *save; struct hdac_device *hdev, *save;
...@@ -739,6 +762,7 @@ static struct pci_driver avs_pci_driver = { ...@@ -739,6 +762,7 @@ static struct pci_driver avs_pci_driver = {
.id_table = avs_ids, .id_table = avs_ids,
.probe = avs_pci_probe, .probe = avs_pci_probe,
.remove = avs_pci_remove, .remove = avs_pci_remove,
.shutdown = avs_pci_shutdown,
.driver = { .driver = {
.pm = &avs_dev_pm, .pm = &avs_dev_pm,
}, },
......
...@@ -497,21 +497,28 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) ...@@ -497,21 +497,28 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
if (adev) { if (adev) {
snprintf(codec_name, sizeof(codec_name), snprintf(codec_name, sizeof(codec_name),
"i2c-%s", acpi_dev_name(adev)); "i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_cht_es8316_dais[dai_index].codecs->name = codec_name; byt_cht_es8316_dais[dai_index].codecs->name = codec_name;
} else { } else {
dev_err(dev, "Error cannot find '%s' dev\n", mach->id); dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
return -ENXIO; return -ENXIO;
} }
codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);
if (!codec_dev)
return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev);
/* override platform name, if required */ /* override platform name, if required */
byt_cht_es8316_card.dev = dev; byt_cht_es8316_card.dev = dev;
platform_name = mach->mach_params.platform; platform_name = mach->mach_params.platform;
ret = snd_soc_fixup_dai_links_platform_name(&byt_cht_es8316_card, ret = snd_soc_fixup_dai_links_platform_name(&byt_cht_es8316_card,
platform_name); platform_name);
if (ret) if (ret) {
put_device(codec_dev);
return ret; return ret;
}
/* Check for BYTCR or other platform and setup quirks */ /* Check for BYTCR or other platform and setup quirks */
dmi_id = dmi_first_match(byt_cht_es8316_quirk_table); dmi_id = dmi_first_match(byt_cht_es8316_quirk_table);
...@@ -539,13 +546,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) ...@@ -539,13 +546,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
/* get the clock */ /* get the clock */
priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3"); priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");
if (IS_ERR(priv->mclk)) if (IS_ERR(priv->mclk)) {
put_device(codec_dev);
return dev_err_probe(dev, PTR_ERR(priv->mclk), "clk_get pmc_plt_clk_3 failed\n"); return dev_err_probe(dev, PTR_ERR(priv->mclk), "clk_get pmc_plt_clk_3 failed\n");
}
codec_dev = acpi_get_first_physical_node(adev);
if (!codec_dev)
return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev);
if (quirk & BYT_CHT_ES8316_JD_INVERTED) if (quirk & BYT_CHT_ES8316_JD_INVERTED)
props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted"); props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
......
...@@ -1636,13 +1636,18 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) ...@@ -1636,13 +1636,18 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
if (adev) { if (adev) {
snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
"i2c-%s", acpi_dev_name(adev)); "i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name; byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name;
} else { } else {
dev_err(dev, "Error cannot find '%s' dev\n", mach->id); dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
return -ENXIO; return -ENXIO;
} }
codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);
if (!codec_dev)
return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev);
/* /*
* swap SSP0 if bytcr is detected * swap SSP0 if bytcr is detected
* (will be overridden if DMI quirk is detected) * (will be overridden if DMI quirk is detected)
...@@ -1717,11 +1722,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) ...@@ -1717,11 +1722,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
byt_rt5640_quirk = quirk_override; byt_rt5640_quirk = quirk_override;
} }
codec_dev = acpi_get_first_physical_node(adev);
if (!codec_dev)
return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev);
if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) { if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev), acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev),
byt_rt5640_hp_elitepad_1000g2_gpios); byt_rt5640_hp_elitepad_1000g2_gpios);
......
...@@ -922,7 +922,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) ...@@ -922,7 +922,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
if (adev) { if (adev) {
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name), snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
"i2c-%s", acpi_dev_name(adev)); "i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name; byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name;
} else { } else {
dev_err(dev, "Error cannot find '%s' dev\n", mach->id); dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
...@@ -930,6 +929,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) ...@@ -930,6 +929,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
} }
codec_dev = acpi_get_first_physical_node(adev); codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);
if (!codec_dev) if (!codec_dev)
return -EPROBE_DEFER; return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev); priv->codec_dev = get_device(codec_dev);
......
...@@ -411,9 +411,9 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) ...@@ -411,9 +411,9 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev)
return -ENOENT; return -ENOENT;
} }
snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev)); snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev));
put_device(&adev->dev);
codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, codec_name); codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, codec_name);
acpi_dev_put(adev);
if (!codec_dev) if (!codec_dev)
return -EPROBE_DEFER; return -EPROBE_DEFER;
......
...@@ -336,6 +336,9 @@ static int create_spk_amp_dai_links(struct device *dev, ...@@ -336,6 +336,9 @@ static int create_spk_amp_dai_links(struct device *dev,
links[*id].platforms = platform_component; links[*id].platforms = platform_component;
links[*id].num_platforms = ARRAY_SIZE(platform_component); links[*id].num_platforms = ARRAY_SIZE(platform_component);
links[*id].dpcm_playback = 1; links[*id].dpcm_playback = 1;
/* firmware-generated echo reference */
links[*id].dpcm_capture = 1;
links[*id].no_pcm = 1; links[*id].no_pcm = 1;
links[*id].cpus = &cpus[*id]; links[*id].cpus = &cpus[*id];
links[*id].num_cpus = 1; links[*id].num_cpus = 1;
......
...@@ -681,7 +681,6 @@ static int sof_es8336_probe(struct platform_device *pdev) ...@@ -681,7 +681,6 @@ static int sof_es8336_probe(struct platform_device *pdev)
if (adev) { if (adev) {
snprintf(codec_name, sizeof(codec_name), snprintf(codec_name, sizeof(codec_name),
"i2c-%s", acpi_dev_name(adev)); "i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
dai_links[0].codecs->name = codec_name; dai_links[0].codecs->name = codec_name;
/* also fixup codec dai name if relevant */ /* also fixup codec dai name if relevant */
...@@ -692,16 +691,19 @@ static int sof_es8336_probe(struct platform_device *pdev) ...@@ -692,16 +691,19 @@ static int sof_es8336_probe(struct platform_device *pdev)
return -ENXIO; return -ENXIO;
} }
ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card,
mach->mach_params.platform);
if (ret)
return ret;
codec_dev = acpi_get_first_physical_node(adev); codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);
if (!codec_dev) if (!codec_dev)
return -EPROBE_DEFER; return -EPROBE_DEFER;
priv->codec_dev = get_device(codec_dev); priv->codec_dev = get_device(codec_dev);
ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card,
mach->mach_params.platform);
if (ret) {
put_device(codec_dev);
return ret;
}
if (quirk & SOF_ES8336_JD_INVERTED) if (quirk & SOF_ES8336_JD_INVERTED)
props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted"); props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted");
......
...@@ -487,8 +487,6 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, ...@@ -487,8 +487,6 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].num_codecs = ARRAY_SIZE(max_98373_components); links[id].num_codecs = ARRAY_SIZE(max_98373_components);
links[id].init = max_98373_spk_codec_init; links[id].init = max_98373_spk_codec_init;
links[id].ops = &max_98373_ops; links[id].ops = &max_98373_ops;
/* feedback stream */
links[id].dpcm_capture = 1;
} else if (sof_nau8825_quirk & } else if (sof_nau8825_quirk &
SOF_MAX98360A_SPEAKER_AMP_PRESENT) { SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
max_98360a_dai_link(&links[id]); max_98360a_dai_link(&links[id]);
...@@ -506,6 +504,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, ...@@ -506,6 +504,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].platforms = platform_component; links[id].platforms = platform_component;
links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].num_platforms = ARRAY_SIZE(platform_component);
links[id].dpcm_playback = 1; links[id].dpcm_playback = 1;
/* feedback stream or firmware-generated echo reference */
links[id].dpcm_capture = 1;
links[id].no_pcm = 1; links[id].no_pcm = 1;
links[id].cpus = &cpus[id]; links[id].cpus = &cpus[id];
links[id].num_cpus = 1; links[id].num_cpus = 1;
......
...@@ -761,8 +761,6 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, ...@@ -761,8 +761,6 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].num_codecs = ARRAY_SIZE(max_98373_components); links[id].num_codecs = ARRAY_SIZE(max_98373_components);
links[id].init = max_98373_spk_codec_init; links[id].init = max_98373_spk_codec_init;
links[id].ops = &max_98373_ops; links[id].ops = &max_98373_ops;
/* feedback stream */
links[id].dpcm_capture = 1;
} else if (sof_rt5682_quirk & } else if (sof_rt5682_quirk &
SOF_MAX98360A_SPEAKER_AMP_PRESENT) { SOF_MAX98360A_SPEAKER_AMP_PRESENT) {
max_98360a_dai_link(&links[id]); max_98360a_dai_link(&links[id]);
...@@ -789,6 +787,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, ...@@ -789,6 +787,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
links[id].platforms = platform_component; links[id].platforms = platform_component;
links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].num_platforms = ARRAY_SIZE(platform_component);
links[id].dpcm_playback = 1; links[id].dpcm_playback = 1;
/* feedback stream or firmware-generated echo reference */
links[id].dpcm_capture = 1;
links[id].no_pcm = 1; links[id].no_pcm = 1;
links[id].cpus = &cpus[id]; links[id].cpus = &cpus[id];
links[id].num_cpus = 1; links[id].num_cpus = 1;
......
...@@ -258,13 +258,12 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, ...@@ -258,13 +258,12 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
sof_rt1308_dai_link(&links[id]); sof_rt1308_dai_link(&links[id]);
} else if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) { } else if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) {
cs35l41_set_dai_link(&links[id]); cs35l41_set_dai_link(&links[id]);
/* feedback from amplifier */
links[id].dpcm_capture = 1;
} }
links[id].platforms = platform_component; links[id].platforms = platform_component;
links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].num_platforms = ARRAY_SIZE(platform_component);
links[id].dpcm_playback = 1; links[id].dpcm_playback = 1;
/* feedback from amplifier or firmware-generated echo reference */
links[id].dpcm_capture = 1;
links[id].no_pcm = 1; links[id].no_pcm = 1;
links[id].cpus = &cpus[id]; links[id].cpus = &cpus[id];
links[id].num_cpus = 1; links[id].num_cpus = 1;
......
...@@ -344,9 +344,10 @@ static ssize_t sof_ipc4_priority_mask_dfs_write(struct file *file, ...@@ -344,9 +344,10 @@ static ssize_t sof_ipc4_priority_mask_dfs_write(struct file *file,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct sof_mtrace_priv *priv = file->private_data; struct sof_mtrace_priv *priv = file->private_data;
int id, ret; unsigned int id;
char *buf; char *buf;
u32 mask; u32 mask;
int ret;
/* /*
* To update Nth mask entry, write: * To update Nth mask entry, write:
...@@ -357,9 +358,9 @@ static ssize_t sof_ipc4_priority_mask_dfs_write(struct file *file, ...@@ -357,9 +358,9 @@ static ssize_t sof_ipc4_priority_mask_dfs_write(struct file *file,
if (IS_ERR(buf)) if (IS_ERR(buf))
return PTR_ERR(buf); return PTR_ERR(buf);
ret = sscanf(buf, "%d,0x%x", &id, &mask); ret = sscanf(buf, "%u,0x%x", &id, &mask);
if (ret != 2) { if (ret != 2) {
ret = sscanf(buf, "%d,%x", &id, &mask); ret = sscanf(buf, "%u,%x", &id, &mask);
if (ret != 2) { if (ret != 2) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
......
...@@ -271,9 +271,9 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg ...@@ -271,9 +271,9 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg
struct snd_sof_widget *swidget = widget->dobj.private; struct snd_sof_widget *swidget = widget->dobj.private;
struct snd_soc_dapm_path *p; struct snd_soc_dapm_path *p;
/* return if the widget is in use or if it is already unprepared */ /* skip if the widget is in use or if it is already unprepared */
if (!swidget->prepared || swidget->use_count > 1) if (!swidget || !swidget->prepared || swidget->use_count > 0)
return; goto sink_unprepare;
if (widget_ops[widget->id].ipc_unprepare) if (widget_ops[widget->id].ipc_unprepare)
/* unprepare the source widget */ /* unprepare the source widget */
...@@ -281,6 +281,7 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg ...@@ -281,6 +281,7 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg
swidget->prepared = false; swidget->prepared = false;
sink_unprepare:
/* unprepare all widgets in the sink paths */ /* unprepare all widgets in the sink paths */
snd_soc_dapm_widget_for_each_sink_path(widget, p) { snd_soc_dapm_widget_for_each_sink_path(widget, p) {
if (!p->walking && p->sink->dobj.private) { if (!p->walking && p->sink->dobj.private) {
...@@ -303,7 +304,7 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget ...@@ -303,7 +304,7 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget
struct snd_soc_dapm_path *p; struct snd_soc_dapm_path *p;
int ret; int ret;
if (!widget_ops[widget->id].ipc_prepare || swidget->prepared) if (!swidget || !widget_ops[widget->id].ipc_prepare || swidget->prepared)
goto sink_prepare; goto sink_prepare;
/* prepare the source widget */ /* prepare the source widget */
...@@ -326,7 +327,8 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget ...@@ -326,7 +327,8 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget
p->walking = false; p->walking = false;
if (ret < 0) { if (ret < 0) {
/* unprepare the source widget */ /* unprepare the source widget */
if (widget_ops[widget->id].ipc_unprepare && swidget->prepared) { if (widget_ops[widget->id].ipc_unprepare &&
swidget && swidget->prepared) {
widget_ops[widget->id].ipc_unprepare(swidget); widget_ops[widget->id].ipc_unprepare(swidget);
swidget->prepared = false; swidget->prepared = false;
} }
...@@ -429,11 +431,11 @@ sof_walk_widgets_in_order(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget_l ...@@ -429,11 +431,11 @@ sof_walk_widgets_in_order(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget_l
for_each_dapm_widgets(list, i, widget) { for_each_dapm_widgets(list, i, widget) {
/* starting widget for playback is AIF type */ /* starting widget for playback is AIF type */
if (dir == SNDRV_PCM_STREAM_PLAYBACK && !WIDGET_IS_AIF(widget->id)) if (dir == SNDRV_PCM_STREAM_PLAYBACK && widget->id != snd_soc_dapm_aif_in)
continue; continue;
/* starting widget for capture is DAI type */ /* starting widget for capture is DAI type */
if (dir == SNDRV_PCM_STREAM_CAPTURE && !WIDGET_IS_DAI(widget->id)) if (dir == SNDRV_PCM_STREAM_CAPTURE && widget->id != snd_soc_dapm_dai_out)
continue; continue;
switch (op) { switch (op) {
......
...@@ -2152,6 +2152,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { ...@@ -2152,6 +2152,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_GENERIC_IMPLICIT_FB), QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */ DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */
QUIRK_FLAG_IFACE_SKIP_CLOSE), QUIRK_FLAG_IFACE_SKIP_CLOSE),
DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */
QUIRK_FLAG_FIXED_RATE),
DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */ DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
QUIRK_FLAG_FIXED_RATE), QUIRK_FLAG_FIXED_RATE),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment