mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 05:55:44 +02:00
sound fixes for 7.1-rc5
As expected, we still continue receiving lots of small fixes. One major change is about HD-audio pending IRQ handling, but this would influence only on odd machines or slow VMs. There are a few other fixes for the core part, but most of them are not-too-serious UAF fixes, while the rest are mostly device-specific fixes and quirks. ALSA Core: - Fix for PCM silencing with bogus iov_iter - Fixes for past-the-end iterators in timer and seq - Serialization of UMP output teardown - Rate-limit ELD parsing errors HD-audio: - Fixes for IRQ work handling and SSID matching - Various Realtek quirks for HP and ASUS laptops, including LED fixes ASoC: - Intel: ACPI match table updates for PTL, NVL, and ARL platforms - Cirrus Logic: Fixes for cs-amp-lib and cs35l56 codecs - Various platform fixes for AMD, FSL SAI, TI OMAP, and Qualcomm - DT-binding fix for MediaTek Others: - USB ua101: Reject too-short USB descriptors - Scarlett2: Fix for flash writes - ASIHPI: Fix for potential OOB access - AMD SPI: Fix for bus number in ACPI probe MAINTAINERS: - Updates for SOF and TI maintainers -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmoQGYEOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE++khAAxtTrTwq5GZMAA0C1OMBI9SxclGABBTaMMkYD lXjX7z/59Iw5YMkIuKEPZUn9Q9huoTd9vgfWUgCANP5zRGO63Tm+jottFco8w+YU KrOvBjy8kQ9GOjrN5Hoy8DKz1tJBz8SXQW08/GEL1gUqHdgxJjunAiYXcTJ+A3jo yL5GASW+C/G1sErpC+ixAlnRRnjt8PP4xtX05BtSQMw4hsEtlalBR20VqCKwUNpi 9T2wxxB8+GwybeFE+3KTl2T3IsFPtUiqDfph54MW+9GaYGVcmxKR98Cs0EAx+ABZ XgnwofwTOSMOfpmjSBG4oCVyWL7RPd8thjcT52qrYECPLWiPwguvO0tc2dnWIiFN m1qsZh7lCEiROZ6ZRefQTLWTHzs/yo2oW41I+owJCERyw23IzuCJm2+JvCyepz4h wBxdnr6lC8DimwAOaqHM0eSmPLBGz//YW+lHwkVIsMMjEhCexm0BVDSjhh1beC0N NijeMeIDVj666hs41AcejWqOutSm37amWaCSpfiWNWqE6tJljPny+p9qwgzunb4d /NLxNSPIQaohQJ12axSR3fMU7FgMK56hzbb3x4t/da++JfJOviOA01zJq3oaHMOK XIpqt5W5c/mNRJWvnOKFXNbOGpLmfsI8ox7mbqZdHFpvqzpK2VDw6jQRMbagPZFL nOjwHWE= =7KbQ -----END PGP SIGNATURE----- Merge tag 'sound-7.1-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "As expected, we still continue receiving lots of small fixes. One major change is about HD-audio pending IRQ handling, but this would influence only on odd machines or slow VMs. There are a few other fixes for the core part, but most of them are not-too-serious UAF fixes, while the rest are mostly device-specific fixes and quirks. ALSA Core: - Fix for PCM silencing with bogus iov_iter - Fixes for past-the-end iterators in timer and seq - Serialization of UMP output teardown - Rate-limit ELD parsing errors HD-audio: - Fixes for IRQ work handling and SSID matching - Various Realtek quirks for HP and ASUS laptops, including LED fixes ASoC: - Intel: ACPI match table updates for PTL, NVL, and ARL platforms - Cirrus Logic: Fixes for cs-amp-lib and cs35l56 codecs - Various platform fixes for AMD, FSL SAI, TI OMAP, and Qualcomm - DT-binding fix for MediaTek Others: - USB ua101: Reject too-short USB descriptors - Scarlett2: Fix for flash writes - ASIHPI: Fix for potential OOB access - AMD SPI: Fix for bus number in ACPI probe MAINTAINERS: - Updates for SOF and TI maintainers" * tag 'sound-7.1-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (47 commits) ASoC: codecs: pcm512x: fix null-ptr dereference in pcm512x_overclock_xxx_put() ASoC: Intel: soc-acpi-intel-ptl-match: Remove unnecessary cs42l43 match ASoC: soc-acpi-intel-ptl-match: Make Chrome matches conditional ASoC: Intel: soc-acpi: Add entry for sof_es8336 in NVL match table. ASoC: Intel: sof_sdw: Add support for nvlrvp in NVL platform ASoC: cs-amp-lib: Fix typo in error message: write -> read ASoC: cs-amp-lib: Fix missing dput() after debugfs_lookup() ASoC: cs-amp-lib: Fix wrong sizeof() in _cs_amp_set_efi_calibration_data() ASoC: cs35l56: Fix flushing of IRQ work in cs35l56_sdw_remove() MAINTAINERS: ASoC: Intel/SOF: Remove Ranjani Sridharan as maintainer ALSA: seq: Serialize UMP output teardown with event_input ALSA: scarlett2: Allow flash writes ending at segment boundary ALSA: hda/realtek: Add LED quirk for HP ProBook 430 G6 ALSA: hda/intel: Make sure to cancel irq-pending work at closing PCM stream ALSA: hda: Move irq pending work into hda-intel stream ASoC: soc-utils: Add missing va_end in snd_soc_ret() ALSA: ua101: Reject too-short USB descriptors ALSA: hda/realtek: Fix mute and mic-mute LEDs for HP 16 Piston OmniBook X ALSA: seq: avoid past-the-end iterator in snd_seq_create_port() ALSA: timer: avoid past-the-end iterator in snd_timer_dev_register() ...
This commit is contained in:
commit
c22407252a
|
|
@ -18,7 +18,9 @@ properties:
|
|||
description: Phandles of rt5650 and rt5514 codecs
|
||||
items:
|
||||
- description: phandle of rt5650 codec
|
||||
maxItems: 1
|
||||
- description: phandle of rt5514 codec
|
||||
maxItems: 1
|
||||
|
||||
mediatek,platform:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
|
|
|||
11
MAINTAINERS
11
MAINTAINERS
|
|
@ -12791,7 +12791,6 @@ M: Cezary Rojewski <cezary.rojewski@intel.com>
|
|||
M: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
M: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
|
||||
M: Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
M: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
|
||||
M: Kai Vehmanen <kai.vehmanen@linux.intel.com>
|
||||
R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
L: linux-sound@vger.kernel.org
|
||||
|
|
@ -19462,7 +19461,6 @@ F: include/misc/ocxl*
|
|||
F: include/uapi/misc/ocxl.h
|
||||
|
||||
OMAP AUDIO SUPPORT
|
||||
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
M: Jarkko Nikula <jarkko.nikula@bitmer.com>
|
||||
L: linux-sound@vger.kernel.org
|
||||
L: linux-omap@vger.kernel.org
|
||||
|
|
@ -25070,7 +25068,6 @@ SOUND - SOUND OPEN FIRMWARE (SOF) DRIVERS
|
|||
M: Liam Girdwood <lgirdwood@gmail.com>
|
||||
M: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
|
||||
M: Bard Liao <yung-chuan.liao@linux.intel.com>
|
||||
M: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
|
||||
M: Daniel Baluta <daniel.baluta@nxp.com>
|
||||
R: Kai Vehmanen <kai.vehmanen@linux.intel.com>
|
||||
R: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
|
||||
|
|
@ -26363,7 +26360,7 @@ F: arch/xtensa/
|
|||
F: drivers/irqchip/irq-xtensa-*
|
||||
|
||||
TEXAS INSTRUMENTS ASoC DRIVERS
|
||||
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
M: Sen Wang <sen@ti.com>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
|
||||
|
|
@ -26865,12 +26862,6 @@ S: Maintained
|
|||
F: Documentation/devicetree/bindings/iio/adc/ti,tsc2046.yaml
|
||||
F: drivers/iio/adc/ti-tsc2046.c
|
||||
|
||||
TI TWL4030 SERIES SOC CODEC DRIVER
|
||||
M: Peter Ujfalusi <peter.ujfalusi@gmail.com>
|
||||
L: linux-sound@vger.kernel.org
|
||||
S: Maintained
|
||||
F: sound/soc/codecs/twl4030*
|
||||
|
||||
TI VPE/CAL DRIVERS
|
||||
M: Yemike Abhilash Chandra <y-abhilashchandra@ti.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
|
|
|
|||
|
|
@ -868,7 +868,7 @@ static int amd_spi_probe(struct platform_device *pdev)
|
|||
dev_dbg(dev, "io_remap_address: %p\n", amd_spi->io_remap_addr);
|
||||
|
||||
amd_spi->version = (uintptr_t)device_get_match_data(dev);
|
||||
host->bus_num = 0;
|
||||
host->bus_num = (amd_spi->version == AMD_HID2_SPI) ? 2 : 0;
|
||||
|
||||
return amd_spi_probe_common(dev, host);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ int snd_parse_eld(struct device *dev, struct snd_parsed_hdmi_eld *e,
|
|||
e->eld_ver = GRAB_BITS(buf, 0, 3, 5);
|
||||
if (e->eld_ver != ELD_VER_CEA_861D &&
|
||||
e->eld_ver != ELD_VER_PARTIAL) {
|
||||
dev_info(dev, "HDMI: Unknown ELD version %d\n", e->eld_ver);
|
||||
dev_info_ratelimited(dev, "HDMI: Unknown ELD version %d\n", e->eld_ver);
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
|
|
@ -357,7 +357,7 @@ int snd_parse_eld(struct device *dev, struct snd_parsed_hdmi_eld *e,
|
|||
e->product_id = get_unaligned_le16(buf + 18);
|
||||
|
||||
if (mnl > ELD_MAX_MNL) {
|
||||
dev_info(dev, "HDMI: MNL is reserved value %d\n", mnl);
|
||||
dev_info_ratelimited(dev, "HDMI: MNL is reserved value %d\n", mnl);
|
||||
goto out_fail;
|
||||
} else if (ELD_FIXED_BYTES + mnl > size) {
|
||||
dev_info(dev, "HDMI: out of range MNL %d\n", mnl);
|
||||
|
|
|
|||
|
|
@ -2138,6 +2138,9 @@ static int interleaved_copy(struct snd_pcm_substream *substream,
|
|||
off = frames_to_bytes(runtime, off);
|
||||
frames = frames_to_bytes(runtime, frames);
|
||||
|
||||
if (!data)
|
||||
return fill_silence(substream, 0, hwoff, NULL, frames);
|
||||
|
||||
return do_transfer(substream, 0, hwoff, data + off, frames, transfer,
|
||||
in_kernel);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,18 +144,21 @@ int snd_seq_create_port(struct snd_seq_client *client, int port,
|
|||
num = max(port, 0);
|
||||
guard(mutex)(&client->ports_mutex);
|
||||
guard(write_lock_irq)(&client->ports_lock);
|
||||
struct list_head *insert_before = &client->ports_list_head;
|
||||
list_for_each_entry(p, &client->ports_list_head, list) {
|
||||
if (p->addr.port == port) {
|
||||
kfree(new_port);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (p->addr.port > num)
|
||||
if (p->addr.port > num) {
|
||||
insert_before = &p->list;
|
||||
break;
|
||||
}
|
||||
if (port < 0) /* auto-probe mode */
|
||||
num = p->addr.port + 1;
|
||||
}
|
||||
/* insert the new port */
|
||||
list_add_tail(&new_port->list, &p->list);
|
||||
list_add_tail(&new_port->list, insert_before);
|
||||
client->num_ports++;
|
||||
new_port->addr.port = num; /* store the port number in the port */
|
||||
sprintf(new_port->name, "port-%d", num);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ struct seq_ump_client {
|
|||
struct snd_ump_endpoint *ump; /* assigned endpoint */
|
||||
int seq_client; /* sequencer client id */
|
||||
int opened[2]; /* current opens for each direction */
|
||||
rwlock_t output_lock; /* protects out_rfile output access */
|
||||
struct snd_rawmidi_file out_rfile; /* rawmidi for output */
|
||||
struct seq_ump_input_buffer input; /* input parser context */
|
||||
void *ump_info[SNDRV_UMP_MAX_BLOCKS + 1]; /* shadow of seq client ump_info */
|
||||
|
|
@ -88,6 +89,7 @@ static int seq_ump_process_event(struct snd_seq_event *ev, int direct,
|
|||
unsigned char type;
|
||||
int len;
|
||||
|
||||
guard(read_lock_irqsave)(&client->output_lock);
|
||||
substream = client->out_rfile.output;
|
||||
if (!substream)
|
||||
return -ENODEV;
|
||||
|
|
@ -106,6 +108,7 @@ static int seq_ump_process_event(struct snd_seq_event *ev, int direct,
|
|||
static int seq_ump_client_open(struct seq_ump_client *client, int dir)
|
||||
{
|
||||
struct snd_ump_endpoint *ump = client->ump;
|
||||
struct snd_rawmidi_file rfile = {};
|
||||
int err;
|
||||
|
||||
guard(mutex)(&ump->open_mutex);
|
||||
|
|
@ -113,9 +116,11 @@ static int seq_ump_client_open(struct seq_ump_client *client, int dir)
|
|||
err = snd_rawmidi_kernel_open(&ump->core, 0,
|
||||
SNDRV_RAWMIDI_LFLG_OUTPUT |
|
||||
SNDRV_RAWMIDI_LFLG_APPEND,
|
||||
&client->out_rfile);
|
||||
&rfile);
|
||||
if (err < 0)
|
||||
return err;
|
||||
scoped_guard(write_lock_irqsave, &client->output_lock)
|
||||
client->out_rfile = rfile;
|
||||
}
|
||||
client->opened[dir]++;
|
||||
return 0;
|
||||
|
|
@ -125,11 +130,19 @@ static int seq_ump_client_open(struct seq_ump_client *client, int dir)
|
|||
static int seq_ump_client_close(struct seq_ump_client *client, int dir)
|
||||
{
|
||||
struct snd_ump_endpoint *ump = client->ump;
|
||||
struct snd_rawmidi_file rfile = {};
|
||||
|
||||
guard(mutex)(&ump->open_mutex);
|
||||
if (!--client->opened[dir])
|
||||
if (dir == STR_OUT)
|
||||
snd_rawmidi_kernel_release(&client->out_rfile);
|
||||
if (!--client->opened[dir]) {
|
||||
if (dir == STR_OUT) {
|
||||
scoped_guard(write_lock_irqsave, &client->output_lock) {
|
||||
rfile = client->out_rfile;
|
||||
client->out_rfile = (struct snd_rawmidi_file){};
|
||||
}
|
||||
if (rfile.rmidi)
|
||||
snd_rawmidi_kernel_release(&rfile);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -467,6 +480,7 @@ static int snd_seq_ump_probe(struct snd_seq_device *dev)
|
|||
|
||||
INIT_WORK(&client->group_notify_work, handle_group_notify);
|
||||
client->ump = ump;
|
||||
rwlock_init(&client->output_lock);
|
||||
|
||||
client->seq_client =
|
||||
snd_seq_create_kernel_client(card, ump->core.device,
|
||||
|
|
|
|||
|
|
@ -1007,6 +1007,7 @@ static int snd_timer_dev_register(struct snd_device *dev)
|
|||
{
|
||||
struct snd_timer *timer = dev->device_data;
|
||||
struct snd_timer *timer1;
|
||||
struct list_head *insert_before = &snd_timer_list;
|
||||
|
||||
if (snd_BUG_ON(!timer || !timer->hw.start || !timer->hw.stop))
|
||||
return -ENXIO;
|
||||
|
|
@ -1016,28 +1017,36 @@ static int snd_timer_dev_register(struct snd_device *dev)
|
|||
|
||||
guard(mutex)(®ister_mutex);
|
||||
list_for_each_entry(timer1, &snd_timer_list, device_list) {
|
||||
if (timer1->tmr_class > timer->tmr_class)
|
||||
if (timer1->tmr_class > timer->tmr_class) {
|
||||
insert_before = &timer1->device_list;
|
||||
break;
|
||||
}
|
||||
if (timer1->tmr_class < timer->tmr_class)
|
||||
continue;
|
||||
if (timer1->card && timer->card) {
|
||||
if (timer1->card->number > timer->card->number)
|
||||
if (timer1->card->number > timer->card->number) {
|
||||
insert_before = &timer1->device_list;
|
||||
break;
|
||||
}
|
||||
if (timer1->card->number < timer->card->number)
|
||||
continue;
|
||||
}
|
||||
if (timer1->tmr_device > timer->tmr_device)
|
||||
if (timer1->tmr_device > timer->tmr_device) {
|
||||
insert_before = &timer1->device_list;
|
||||
break;
|
||||
}
|
||||
if (timer1->tmr_device < timer->tmr_device)
|
||||
continue;
|
||||
if (timer1->tmr_subdevice > timer->tmr_subdevice)
|
||||
if (timer1->tmr_subdevice > timer->tmr_subdevice) {
|
||||
insert_before = &timer1->device_list;
|
||||
break;
|
||||
}
|
||||
if (timer1->tmr_subdevice < timer->tmr_subdevice)
|
||||
continue;
|
||||
/* conflicts.. */
|
||||
return -EBUSY;
|
||||
}
|
||||
list_add_tail(&timer->device_list, &timer1->device_list);
|
||||
list_add_tail(&timer->device_list, insert_before);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6955,6 +6955,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN),
|
||||
SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
|
||||
SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360),
|
||||
SND_PCI_QUIRK(0x103c, 0x8536, "HP ProBook 430 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8537, "HP ProBook 440 G6", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8548, "HP EliteBook x360 830 G6", ALC285_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x854a, "HP EliteBook 830 G6", ALC285_FIXUP_HP_GPIO_LED),
|
||||
|
|
@ -7084,6 +7085,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x103c, 0x8a30, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a31, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a34, "HP Pavilion x360 2-in-1 Laptop 14-ek0xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a36, "HP Pavilion Plus 14-eh0xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a3d, "HP Victus 15-fb0xxx (MB 8A3D)", ALC245_FIXUP_HP_MUTE_LED_V2_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a4f, "HP Victus 15-fa0xxx (MB 8A4F)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
|
||||
SND_PCI_QUIRK(0x103c, 0x8a6e, "HP EDNA 360", ALC287_FIXUP_CS35L41_I2C_4),
|
||||
|
|
@ -7103,6 +7105,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x103c, 0x8ad8, "HP 800 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b0f, "HP Elite mt645 G7 Mobile Thin Client U81", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b2f, "HP 255 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b34, "HP 250 15.6 inch G10 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b3a, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b3f, "HP mt440 Mobile Thin Client U91", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8b42, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED),
|
||||
|
|
@ -7229,7 +7232,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x103c, 0x8da0, "HP 16 Clipper OmniBook 7(X360)", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8da1, "HP 16 Clipper OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8da7, "HP 14 Enstrom OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8da8, "HP 16 Piston OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x103c, 0x8da8, "HP 16 Piston OmniBook X", ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dc9, "HP Laptop 15-fc0xxx", ALC236_FIXUP_HP_DMIC),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dd4, "HP EliteStudio 8 AIO", ALC274_FIXUP_HP_AIO_BIND_DACS),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dd7, "HP Laptop 15-fd0xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
|
||||
|
|
@ -7241,6 +7244,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x103c, 0x8def, "HP EliteBook 660 G12", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8df0, "HP EliteBook 630 G12", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8df1, "HP EliteBook 630 G12", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8df7, "HP Z66 G6", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dfb, "HP EliteBook 6 G1a 14", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dfc, "HP EliteBook 645 G12", ALC236_FIXUP_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8dfd, "HP EliteBook 6 G1a 16", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
|
||||
|
|
@ -7453,12 +7457,12 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1043, 0x3e00, "ASUS G814FH/FM/FP", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x3e20, "ASUS G814PH/PM/PP", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x3e30, "ASUS TP3607SA", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3ee0, "ASUS Strix G815_JHR_JMR_JPR", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3ef0, "ASUS Strix G635LR_LW_LX", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f00, "ASUS Strix G815LH_LM_LP", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f10, "ASUS Strix G835LR_LW_LX", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f20, "ASUS Strix G615LR_LW", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f30, "ASUS Strix G815LR_LW", ALC287_FIXUP_TAS2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3ee0, "ASUS Strix G815_JHR_JMR_JPR", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3ef0, "ASUS Strix G635LR_LW_LX", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f00, "ASUS Strix G815LH_LM_LP", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f10, "ASUS Strix G835LR_LW_LX", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f20, "ASUS Strix G615LR_LW", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3f30, "ASUS Strix G815LR_LW", ALC287_FIXUP_TXNW2781_I2C),
|
||||
SND_PCI_QUIRK(0x1043, 0x3fd0, "ASUS B3605CVA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x3ff0, "ASUS B5405CVA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
|
||||
|
|
|
|||
|
|
@ -1013,7 +1013,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
|
|||
const char *name = NULL;
|
||||
const char *type = NULL;
|
||||
unsigned int vendor, device;
|
||||
u16 pci_vendor, pci_device;
|
||||
u16 pci_vendor = 0, pci_device = 0;
|
||||
u16 codec_vendor, codec_device;
|
||||
|
||||
if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
|
||||
|
|
@ -1066,7 +1066,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
|
|||
/* match primarily with the PCI SSID */
|
||||
for (q = quirk; q->subvendor || q->subdevice; q++) {
|
||||
/* if the entry is specific to codec SSID, check with it */
|
||||
if (!codec->bus->pci || q->match_codec_ssid) {
|
||||
if (!pci_vendor || !pci_device || q->match_codec_ssid) {
|
||||
if (hda_quirk_match(codec_vendor, codec_device, q)) {
|
||||
type = "codec SSID";
|
||||
goto found_device;
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
|
|||
|
||||
trace_azx_pcm_close(chip, azx_dev);
|
||||
scoped_guard(mutex, &chip->open_mutex) {
|
||||
if (chip->ops->pcm_close)
|
||||
chip->ops->pcm_close(chip, azx_dev);
|
||||
azx_release_device(azx_dev);
|
||||
if (hinfo->ops.close)
|
||||
hinfo->ops.close(hinfo, apcm->codec, substream);
|
||||
|
|
@ -1264,19 +1266,17 @@ int azx_codec_configure(struct azx *chip)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(azx_codec_configure);
|
||||
|
||||
static int stream_direction(struct azx *chip, unsigned char index)
|
||||
void azx_add_stream(struct azx *chip, struct azx_dev *azx_dev, int idx, int tag)
|
||||
{
|
||||
if (index >= chip->capture_index_offset &&
|
||||
index < chip->capture_index_offset + chip->capture_streams)
|
||||
return SNDRV_PCM_STREAM_CAPTURE;
|
||||
return SNDRV_PCM_STREAM_PLAYBACK;
|
||||
snd_hdac_stream_init(azx_bus(chip), azx_stream(azx_dev), idx,
|
||||
azx_stream_direction(chip, idx), tag);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(azx_add_stream);
|
||||
|
||||
/* initialize SD streams */
|
||||
int azx_init_streams(struct azx *chip)
|
||||
{
|
||||
int i;
|
||||
int stream_tags[2] = { 0, 0 };
|
||||
|
||||
/* initialize each stream (aka device)
|
||||
* assign the starting bdl address to each stream (device)
|
||||
|
|
@ -1284,24 +1284,10 @@ int azx_init_streams(struct azx *chip)
|
|||
*/
|
||||
for (i = 0; i < chip->num_streams; i++) {
|
||||
struct azx_dev *azx_dev = kzalloc_obj(*azx_dev);
|
||||
int dir, tag;
|
||||
|
||||
if (!azx_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
dir = stream_direction(chip, i);
|
||||
/* stream tag must be unique throughout
|
||||
* the stream direction group,
|
||||
* valid values 1...15
|
||||
* use separate stream tag if the flag
|
||||
* AZX_DCAPS_SEPARATE_STREAM_TAG is used
|
||||
*/
|
||||
if (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG)
|
||||
tag = ++stream_tags[dir];
|
||||
else
|
||||
tag = i + 1;
|
||||
snd_hdac_stream_init(azx_bus(chip), azx_stream(azx_dev),
|
||||
i, dir, tag);
|
||||
azx_add_stream(chip, azx_dev, i, i + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -57,13 +57,12 @@ enum {
|
|||
struct azx_dev {
|
||||
struct hdac_stream core;
|
||||
|
||||
unsigned int irq_pending:1;
|
||||
/*
|
||||
* For VIA:
|
||||
* A flag to ensure DMA position is 0
|
||||
* when link position is not greater than FIFO size
|
||||
*/
|
||||
unsigned int insufficient:1;
|
||||
bool insufficient;
|
||||
};
|
||||
|
||||
#define azx_stream(dev) (&(dev)->core)
|
||||
|
|
@ -79,6 +78,8 @@ struct hda_controller_ops {
|
|||
int (*position_check)(struct azx *chip, struct azx_dev *azx_dev);
|
||||
/* enable/disable the link power */
|
||||
int (*link_power)(struct azx *chip, bool enable);
|
||||
/* additional hook for PCM */
|
||||
void (*pcm_close)(struct azx *chip, struct azx_dev *azx_dev);
|
||||
};
|
||||
|
||||
struct azx_pcm {
|
||||
|
|
@ -206,6 +207,15 @@ int azx_bus_init(struct azx *chip, const char *model);
|
|||
int azx_probe_codecs(struct azx *chip, unsigned int max_slots);
|
||||
int azx_codec_configure(struct azx *chip);
|
||||
int azx_init_streams(struct azx *chip);
|
||||
void azx_add_stream(struct azx *chip, struct azx_dev *s, int idx, int tag);
|
||||
void azx_free_streams(struct azx *chip);
|
||||
|
||||
static inline int azx_stream_direction(struct azx *chip, unsigned char index)
|
||||
{
|
||||
if (index >= chip->capture_index_offset &&
|
||||
index < chip->capture_index_offset + chip->capture_streams)
|
||||
return SNDRV_PCM_STREAM_CAPTURE;
|
||||
return SNDRV_PCM_STREAM_PLAYBACK;
|
||||
}
|
||||
|
||||
#endif /* __SOUND_HDA_CONTROLLER_H */
|
||||
|
|
|
|||
|
|
@ -615,17 +615,17 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
|
|||
/* called from IRQ */
|
||||
static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
|
||||
{
|
||||
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
||||
struct hda_intel_stream *istream = azx_dev_to_istream(azx_dev);
|
||||
int ok;
|
||||
|
||||
ok = azx_position_ok(chip, azx_dev);
|
||||
if (ok == 1) {
|
||||
azx_dev->irq_pending = 0;
|
||||
istream->irq_pending = false;
|
||||
return ok;
|
||||
} else if (ok == 0) {
|
||||
/* bogus IRQ, process it later */
|
||||
azx_dev->irq_pending = 1;
|
||||
schedule_work(&hda->irq_pending_work);
|
||||
istream->irq_pending = true;
|
||||
schedule_work(&istream->irq_pending_work);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -721,11 +721,13 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
|
|||
*/
|
||||
static void azx_irq_pending_work(struct work_struct *work)
|
||||
{
|
||||
struct hda_intel *hda = container_of(work, struct hda_intel, irq_pending_work);
|
||||
struct hda_intel_stream *istream =
|
||||
container_of(work, struct hda_intel_stream, irq_pending_work);
|
||||
struct azx_dev *azx_dev = &istream->azx_dev;
|
||||
struct hda_intel *hda = istream->hda;
|
||||
struct azx *chip = &hda->chip;
|
||||
struct hdac_bus *bus = azx_bus(chip);
|
||||
struct hdac_stream *s;
|
||||
int pending, ok;
|
||||
int ok;
|
||||
|
||||
if (!hda->irq_pending_warned) {
|
||||
dev_info(chip->card->dev,
|
||||
|
|
@ -735,42 +737,51 @@ static void azx_irq_pending_work(struct work_struct *work)
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
pending = 0;
|
||||
spin_lock_irq(&bus->reg_lock);
|
||||
list_for_each_entry(s, &bus->stream_list, list) {
|
||||
struct azx_dev *azx_dev = stream_to_azx_dev(s);
|
||||
if (!azx_dev->irq_pending ||
|
||||
!s->substream ||
|
||||
!s->running)
|
||||
continue;
|
||||
scoped_guard(spinlock_irq, &bus->reg_lock) {
|
||||
if (!istream->irq_pending ||
|
||||
!azx_dev->core.substream ||
|
||||
!azx_dev->core.running) {
|
||||
return;
|
||||
}
|
||||
|
||||
ok = azx_position_ok(chip, azx_dev);
|
||||
if (ok > 0) {
|
||||
azx_dev->irq_pending = 0;
|
||||
spin_unlock(&bus->reg_lock);
|
||||
snd_pcm_period_elapsed(s->substream);
|
||||
spin_lock(&bus->reg_lock);
|
||||
} else if (ok < 0) {
|
||||
pending = 0; /* too early */
|
||||
} else
|
||||
pending++;
|
||||
if (ok < 0)
|
||||
return; /* too early */
|
||||
if (ok > 0)
|
||||
istream->irq_pending = false;
|
||||
}
|
||||
spin_unlock_irq(&bus->reg_lock);
|
||||
if (!pending)
|
||||
|
||||
if (ok) {
|
||||
snd_pcm_period_elapsed(azx_dev->core.substream);
|
||||
return;
|
||||
}
|
||||
|
||||
msleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear irq_pending flags and assure no on-going workq */
|
||||
static void hda_intel_stream_clear_irq_pending(struct azx_dev *azx_dev)
|
||||
{
|
||||
struct hda_intel_stream *istream = azx_dev_to_istream(azx_dev);
|
||||
|
||||
istream->irq_pending = false;
|
||||
cancel_work_sync(&istream->irq_pending_work);
|
||||
}
|
||||
|
||||
/* called at PCM close */
|
||||
static void hda_intel_pcm_close(struct azx *chip, struct azx_dev *azx_dev)
|
||||
{
|
||||
hda_intel_stream_clear_irq_pending(azx_dev);
|
||||
}
|
||||
|
||||
static void azx_clear_irq_pending(struct azx *chip)
|
||||
{
|
||||
struct hdac_bus *bus = azx_bus(chip);
|
||||
struct hdac_stream *s;
|
||||
|
||||
guard(spinlock_irq)(&bus->reg_lock);
|
||||
list_for_each_entry(s, &bus->stream_list, list) {
|
||||
struct azx_dev *azx_dev = stream_to_azx_dev(s);
|
||||
azx_dev->irq_pending = 0;
|
||||
hda_intel_stream_clear_irq_pending(stream_to_azx_dev(s));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1797,7 +1808,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
|||
if (jackpoll_ms[dev] >= 50 && jackpoll_ms[dev] <= 60000)
|
||||
chip->jackpoll_interval = msecs_to_jiffies(jackpoll_ms[dev]);
|
||||
INIT_LIST_HEAD(&chip->pcm_list);
|
||||
INIT_WORK(&hda->irq_pending_work, azx_irq_pending_work);
|
||||
INIT_LIST_HEAD(&hda->list);
|
||||
init_vga_switcheroo(chip);
|
||||
init_completion(&hda->probe_wait);
|
||||
|
|
@ -1846,6 +1856,39 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* create and assign streams */
|
||||
static int hda_init_streams(struct azx *chip)
|
||||
{
|
||||
int i;
|
||||
int stream_tags[2] = { 0, 0 };
|
||||
|
||||
for (i = 0; i < chip->num_streams; i++) {
|
||||
struct hda_intel_stream *s = kzalloc_obj(*s);
|
||||
int tag, dir;
|
||||
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
s->hda = container_of(chip, struct hda_intel, chip);
|
||||
INIT_WORK(&s->irq_pending_work, azx_irq_pending_work);
|
||||
|
||||
/* stream tag must be unique throughout
|
||||
* the stream direction group,
|
||||
* valid values 1...15
|
||||
* use separate stream tag if the flag
|
||||
* AZX_DCAPS_SEPARATE_STREAM_TAG is used
|
||||
*/
|
||||
dir = azx_stream_direction(chip, i);
|
||||
if (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG)
|
||||
tag = ++stream_tags[dir];
|
||||
else
|
||||
tag = i + 1;
|
||||
azx_add_stream(chip, &s->azx_dev, i, tag);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int azx_first_init(struct azx *chip)
|
||||
{
|
||||
int dev = chip->dev_index;
|
||||
|
|
@ -2000,7 +2043,7 @@ static int azx_first_init(struct azx *chip)
|
|||
}
|
||||
|
||||
/* initialize streams */
|
||||
err = azx_init_streams(chip);
|
||||
err = hda_init_streams(chip);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
@ -2099,6 +2142,7 @@ static const struct dmi_system_id driver_denylist_dmi[] = {
|
|||
static const struct hda_controller_ops pci_hda_ops = {
|
||||
.disable_msi_reset_irq = disable_msi_reset_irq,
|
||||
.position_check = azx_position_check,
|
||||
.pcm_close = hda_intel_pcm_close,
|
||||
};
|
||||
|
||||
static DECLARE_BITMAP(probed_devs, SNDRV_CARDS);
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@
|
|||
struct hda_intel {
|
||||
struct azx chip;
|
||||
|
||||
/* for pending irqs */
|
||||
struct work_struct irq_pending_work;
|
||||
|
||||
/* sync probing */
|
||||
struct completion probe_wait;
|
||||
struct delayed_work probe_work;
|
||||
|
|
@ -35,4 +32,16 @@ struct hda_intel {
|
|||
int probe_retry; /* being probe-retry */
|
||||
};
|
||||
|
||||
struct hda_intel_stream {
|
||||
struct azx_dev azx_dev;
|
||||
|
||||
/* for pending irqs */
|
||||
struct hda_intel *hda;
|
||||
struct work_struct irq_pending_work;
|
||||
bool irq_pending;
|
||||
};
|
||||
|
||||
#define azx_dev_to_istream(azx_dev) \
|
||||
container_of(azx_dev, struct hda_intel_stream, azx_dev)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -276,6 +276,12 @@ static short find_control(u16 control_index,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (control_index >= p_cache->control_count) {
|
||||
HPI_DEBUG_LOG(VERBOSE, "control_index out of bounce %d\n",
|
||||
control_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pI = p_cache->p_info[control_index];
|
||||
if (!*pI) {
|
||||
HPI_DEBUG_LOG(VERBOSE, "Uncached Control %d\n",
|
||||
|
|
|
|||
|
|
@ -30,6 +30,13 @@ static const struct dmi_system_id acp70_acpi_flag_override_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "HN7306EA"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* ASUS Zenbook S16 UM5606GA (Strix Point, ACP 7.0) */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Zenbook S16 UM5606GA"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -260,9 +260,9 @@ static int create_sdw_dailink(struct snd_soc_card *card,
|
|||
cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"SDW%d Pin%d",
|
||||
link_num, cpu_pin_id);
|
||||
dev_dbg(dev, "cpu->dai_name:%s\n", cpus->dai_name);
|
||||
if (!cpus->dai_name)
|
||||
return -ENOMEM;
|
||||
dev_dbg(dev, "cpu->dai_name:%s\n", cpus->dai_name);
|
||||
|
||||
codec_maps[j].cpu = 0;
|
||||
codec_maps[j].codec = j;
|
||||
|
|
|
|||
|
|
@ -898,7 +898,6 @@ menu "CS35L56 driver options"
|
|||
|
||||
config SND_SOC_CS35L56_CAL_DEBUGFS
|
||||
bool "CS35L56 create debugfs for factory calibration"
|
||||
default N
|
||||
depends on DEBUG_FS
|
||||
select SND_SOC_CS35L56_CAL_DEBUGFS_COMMON
|
||||
help
|
||||
|
|
@ -909,7 +908,6 @@ config SND_SOC_CS35L56_CAL_DEBUGFS
|
|||
|
||||
config SND_SOC_CS35L56_CAL_SET_CTRL
|
||||
bool "CS35L56 ALSA control to restore factory calibration"
|
||||
default N
|
||||
select SND_SOC_CS35L56_CAL_DEBUGFS_COMMON
|
||||
help
|
||||
Allow restoring factory calibration data through an ALSA
|
||||
|
|
@ -923,7 +921,6 @@ config SND_SOC_CS35L56_CAL_SET_CTRL
|
|||
|
||||
config SND_SOC_CS35L56_CAL_PERFORM_CTRL
|
||||
bool "CS35L56 ALSA control to perform factory calibration"
|
||||
default N
|
||||
select SND_SOC_CS35L56_CAL_DEBUGFS_COMMON
|
||||
help
|
||||
Allow performing factory calibration data through an ALSA
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ static int cs_amp_read_cal_coeff(struct cs_dsp *dsp,
|
|||
}
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(dsp->dev, "Failed to write to '%s': %d\n", ctl_name, ret);
|
||||
dev_err(dsp->dev, "Failed to read '%s': %d\n", ctl_name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -500,7 +500,7 @@ static int _cs_amp_set_efi_calibration_data(struct device *dev, int amp_index, i
|
|||
* must be set.
|
||||
*/
|
||||
if (data->count == 0)
|
||||
data->count = (data->size - sizeof(data)) / sizeof(data->data[0]);
|
||||
data->count = (data->size - struct_offset(data, data)) / sizeof(data->data[0]);
|
||||
|
||||
if (amp_index < 0) {
|
||||
/* Is there already a slot for this target? */
|
||||
|
|
@ -833,11 +833,18 @@ EXPORT_SYMBOL_NS_GPL(cs_amp_devm_get_vendor_specific_variant_id, "SND_SOC_CS_AMP
|
|||
*/
|
||||
struct dentry *cs_amp_create_debugfs(struct device *dev)
|
||||
{
|
||||
struct dentry *dir;
|
||||
struct dentry *dir, *created;
|
||||
|
||||
/* debugfs_lookup() can return NULL or ERR_PTR on error */
|
||||
dir = debugfs_lookup("cirrus_logic", NULL);
|
||||
if (!dir)
|
||||
dir = debugfs_create_dir("cirrus_logic", NULL);
|
||||
if (!IS_ERR_OR_NULL(dir)) {
|
||||
created = debugfs_create_dir(dev_name(dev), dir);
|
||||
dput(dir);
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
dir = debugfs_create_dir("cirrus_logic", NULL);
|
||||
|
||||
return debugfs_create_dir(dev_name(dev), dir);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -385,18 +385,19 @@ static int cs35l56_sdw_update_status(struct sdw_slave *peripheral,
|
|||
|
||||
switch (status) {
|
||||
case SDW_SLAVE_ATTACHED:
|
||||
dev_dbg(cs35l56->base.dev, "%s: ATTACHED\n", __func__);
|
||||
cs35l56->sdw_in_clock_stop_1 = false;
|
||||
if (cs35l56->sdw_attached)
|
||||
break;
|
||||
|
||||
dev_dbg(cs35l56->base.dev, "%s: ATTACHED\n", __func__);
|
||||
if (!cs35l56->base.init_done || cs35l56->soft_resetting)
|
||||
cs35l56_sdw_init(peripheral);
|
||||
|
||||
cs35l56->sdw_attached = true;
|
||||
break;
|
||||
case SDW_SLAVE_UNATTACHED:
|
||||
dev_dbg(cs35l56->base.dev, "%s: UNATTACHED\n", __func__);
|
||||
if (cs35l56->sdw_attached)
|
||||
dev_dbg(cs35l56->base.dev, "%s: UNATTACHED\n", __func__);
|
||||
cs35l56->sdw_attached = false;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -584,10 +585,11 @@ static void cs35l56_sdw_remove(struct sdw_slave *peripheral)
|
|||
|
||||
/* Disable SoundWire interrupts */
|
||||
cs35l56->sdw_irq_no_unmask = true;
|
||||
cancel_work_sync(&cs35l56->sdw_irq_work);
|
||||
flush_work(&cs35l56->sdw_irq_work);
|
||||
sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_MASK_1, 0);
|
||||
sdw_read_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1);
|
||||
sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF);
|
||||
flush_work(&cs35l56->sdw_irq_work);
|
||||
|
||||
cs35l56_remove(cs35l56);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -867,11 +867,16 @@ static void cs35l56_dsp_work(struct work_struct *work)
|
|||
if (!cs35l56->base.init_done)
|
||||
return;
|
||||
|
||||
pm_runtime_get_sync(cs35l56->base.dev);
|
||||
PM_RUNTIME_ACQUIRE(cs35l56->base.dev, pm);
|
||||
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
|
||||
if (ret) {
|
||||
dev_err(cs35l56->base.dev, "dsp_work failed to runtime-resume: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = cs35l56_read_prot_status(&cs35l56->base, &firmware_missing, &firmware_version);
|
||||
if (ret)
|
||||
goto err;
|
||||
return;
|
||||
|
||||
/* Populate fw file qualifier with the revision and security state */
|
||||
kfree(cs35l56->dsp.fwf_name);
|
||||
|
|
@ -887,7 +892,7 @@ static void cs35l56_dsp_work(struct work_struct *work)
|
|||
}
|
||||
|
||||
if (!cs35l56->dsp.fwf_name)
|
||||
goto err;
|
||||
return;
|
||||
|
||||
dev_dbg(cs35l56->base.dev, "DSP fwf name: '%s' system name: '%s'\n",
|
||||
cs35l56->dsp.fwf_name, cs35l56->dsp.system_name);
|
||||
|
|
@ -905,8 +910,6 @@ static void cs35l56_dsp_work(struct work_struct *work)
|
|||
cs35l56_patch(cs35l56, firmware_missing);
|
||||
|
||||
cs35l56_log_tuning(&cs35l56->base, &cs35l56->dsp.cs_dsp);
|
||||
err:
|
||||
pm_runtime_put_autosuspend(cs35l56->base.dev);
|
||||
}
|
||||
|
||||
static struct snd_soc_dapm_context *cs35l56_power_up_for_cal(struct cs35l56_private *cs35l56)
|
||||
|
|
|
|||
|
|
@ -968,7 +968,7 @@ static int fs210x_effect_scene_info(struct snd_kcontrol *kcontrol,
|
|||
if (scene->name)
|
||||
name = scene->name;
|
||||
|
||||
strscpy(uinfo->value.enumerated.name, name, strlen(name) + 1);
|
||||
strscpy(uinfo->value.enumerated.name, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
|
|||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
|
||||
struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (snd_soc_dapm_get_bias_level(dapm)) {
|
||||
|
|
@ -264,7 +264,7 @@ static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
|
|||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
|
||||
struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (snd_soc_dapm_get_bias_level(dapm)) {
|
||||
|
|
@ -293,7 +293,7 @@ static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol,
|
|||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
|
||||
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
|
||||
struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (snd_soc_dapm_get_bias_level(dapm)) {
|
||||
|
|
|
|||
|
|
@ -1370,6 +1370,31 @@ static int fsl_sai_check_version(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fsl_sai_reset_hw(struct device *dev)
|
||||
{
|
||||
struct fsl_sai *sai = dev_get_drvdata(dev);
|
||||
unsigned char ofs = sai->soc_data->reg_offset;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Clear TCSR/RCSR to reset SAI and disable all interrupts.
|
||||
* Bootloader may leave SAI running causing interrupt storm.
|
||||
*/
|
||||
ret = regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to clear TCSR: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to clear RCSR: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the offset between first two datalines, don't
|
||||
* different offset in one case.
|
||||
|
|
@ -1575,13 +1600,6 @@ static int fsl_sai_probe(struct platform_device *pdev)
|
|||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
ret = devm_request_irq(dev, irq, fsl_sai_isr, IRQF_SHARED,
|
||||
np->name, sai);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to claim irq %u\n", irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(&sai->cpu_dai_drv, fsl_sai_dai_template,
|
||||
sizeof(*fsl_sai_dai_template) * ARRAY_SIZE(fsl_sai_dai_template));
|
||||
|
||||
|
|
@ -1656,6 +1674,10 @@ static int fsl_sai_probe(struct platform_device *pdev)
|
|||
if (ret < 0)
|
||||
dev_warn(dev, "Error reading SAI version: %d\n", ret);
|
||||
|
||||
ret = fsl_sai_reset_hw(dev);
|
||||
if (ret < 0)
|
||||
dev_warn(dev, "Failed to reset hardware: %d\n", ret);
|
||||
|
||||
/* Select MCLK direction */
|
||||
if (sai->mclk_direction_output &&
|
||||
sai->soc_data->max_register >= FSL_SAI_MCTL) {
|
||||
|
|
@ -1667,6 +1689,13 @@ static int fsl_sai_probe(struct platform_device *pdev)
|
|||
if (ret < 0 && ret != -ENOSYS)
|
||||
goto err_pm_get_sync;
|
||||
|
||||
ret = devm_request_irq(dev, irq, fsl_sai_isr, IRQF_SHARED,
|
||||
np->name, sai);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to claim irq %u\n", irq);
|
||||
goto err_pm_get_sync;
|
||||
}
|
||||
|
||||
if (of_device_is_compatible(np, "fsl,imx952-sai") &&
|
||||
!of_property_read_string(np, "fsl,sai-amix-mode", &str)) {
|
||||
if (!strcmp(str, "bypass"))
|
||||
|
|
|
|||
|
|
@ -837,6 +837,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
|
|||
SOF_BT_OFFLOAD_SSP(2) |
|
||||
SOF_SSP_BT_OFFLOAD_PRESENT),
|
||||
},
|
||||
/* Novalake devices*/
|
||||
{
|
||||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_nvlrvp"),
|
||||
},
|
||||
.driver_data = (void *)(SOC_SDW_PCH_DMIC),
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <sound/soc-acpi.h>
|
||||
#include <sound/soc-acpi-intel-match.h>
|
||||
#include <sound/soc-acpi-intel-ssp-common.h>
|
||||
#include "soc-acpi-intel-sdca-quirks.h"
|
||||
#include "sof-function-topology-lib.h"
|
||||
|
||||
static const struct snd_soc_acpi_endpoint single_endpoint = {
|
||||
|
|
@ -237,6 +238,15 @@ static const struct snd_soc_acpi_adr_device rt722_0_agg_adr[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt712_0_agg_adr[] = {
|
||||
{
|
||||
.adr = 0x000030025D071201ull,
|
||||
.num_endpoints = ARRAY_SIZE(jack_amp_g1_dmic_endpoints),
|
||||
.endpoints = jack_amp_g1_dmic_endpoints,
|
||||
.name_prefix = "rt712"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1316_3_single_adr[] = {
|
||||
{
|
||||
.adr = 0x000330025D131601ull,
|
||||
|
|
@ -255,6 +265,15 @@ static const struct snd_soc_acpi_adr_device rt1320_2_single_adr[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1320_3_group1_adr[] = {
|
||||
{
|
||||
.adr = 0x000330025D132001ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_r_endpoint,
|
||||
.name_prefix = "rt1320-1"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr arl_cs42l43_l0[] = {
|
||||
{
|
||||
.mask = BIT(0),
|
||||
|
|
@ -404,6 +423,20 @@ static const struct snd_soc_acpi_link_adr arl_rt722_l0_rt1320_l2[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr arl_rt712_l0_rt1320_l3[] = {
|
||||
{
|
||||
.mask = BIT(0),
|
||||
.num_adr = ARRAY_SIZE(rt712_0_agg_adr),
|
||||
.adr_d = rt712_0_agg_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(3),
|
||||
.num_adr = ARRAY_SIZE(rt1320_3_group1_adr),
|
||||
.adr_d = rt1320_3_group1_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_codecs arl_essx_83x6 = {
|
||||
.num_codecs = 3,
|
||||
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
|
||||
|
|
@ -483,10 +516,24 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = {
|
|||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0),
|
||||
.links = arl_cs42l43_l0,
|
||||
.link_mask = BIT(0) | BIT(2),
|
||||
.links = arl_rt722_l0_rt1320_l2,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-arl-cs42l43-l0.tplg",
|
||||
.sof_tplg_filename = "sof-arl-rt722-l0_rt1320-l2.tplg",
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(3),
|
||||
.links = arl_rt711_l0_rt1316_l3,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-arl-rt711-l0-rt1316-l3.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(3),
|
||||
.links = arl_rt712_l0_rt1320_l3,
|
||||
.drv_name = "sof_sdw",
|
||||
.machine_check = snd_soc_acpi_intel_sdca_is_device_rt712_vb,
|
||||
.sof_tplg_filename = "sof-arl-rt712-l0-rt1320-l3.tplg",
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
|
|
@ -497,18 +544,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = {
|
|||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(2),
|
||||
.links = arl_cs42l43_l2,
|
||||
.link_mask = BIT(0),
|
||||
.links = arl_cs42l43_l0,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-arl-cs42l43-l2.tplg",
|
||||
.sof_tplg_filename = "sof-arl-cs42l43-l0.tplg",
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(3),
|
||||
.links = arl_rt711_l0_rt1316_l3,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-arl-rt711-l0-rt1316-l3.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = 0x1, /* link0 required */
|
||||
.links = arl_rvp,
|
||||
|
|
@ -522,10 +563,10 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = {
|
|||
.sof_tplg_filename = "sof-arl-rt711-l0.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(2),
|
||||
.links = arl_rt722_l0_rt1320_l2,
|
||||
.link_mask = BIT(2),
|
||||
.links = arl_cs42l43_l2,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-arl-rt722-l0_rt1320-l2.tplg",
|
||||
.sof_tplg_filename = "sof-arl-cs42l43-l2.tplg",
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{},
|
||||
|
|
|
|||
|
|
@ -10,7 +10,20 @@
|
|||
#include <sound/soc-acpi-intel-match.h>
|
||||
#include "soc-acpi-intel-sdw-mockup-match.h"
|
||||
|
||||
static const struct snd_soc_acpi_codecs nvl_essx_83x6 = {
|
||||
.num_codecs = 3,
|
||||
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
|
||||
};
|
||||
|
||||
struct snd_soc_acpi_mach snd_soc_acpi_intel_nvl_machines[] = {
|
||||
{
|
||||
.comp_ids = &nvl_essx_83x6,
|
||||
.drv_name = "sof-essx8336",
|
||||
.sof_tplg_filename = "sof-nvl-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_nvl_machines);
|
||||
|
|
|
|||
|
|
@ -92,48 +92,6 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
|
|||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_1_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 1,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 2,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 3,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_4_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 4,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_5_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 5,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint spk_6_endpoint = {
|
||||
.num = 0,
|
||||
.aggregated = 1,
|
||||
.group_position = 6,
|
||||
.group_id = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_endpoint jack_dmic_endpoints[] = {
|
||||
/* Jack Endpoint */
|
||||
{
|
||||
|
|
@ -202,15 +160,6 @@ static const struct snd_soc_acpi_endpoint cs42l43_amp_spkagg_endpoints[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = {
|
||||
{
|
||||
.adr = 0x00023001fa424301ull,
|
||||
.num_endpoints = ARRAY_SIZE(cs42l43_amp_spkagg_endpoints),
|
||||
.endpoints = cs42l43_amp_spkagg_endpoints,
|
||||
.name_prefix = "cs42l43"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device cs42l43_3_agg_adr[] = {
|
||||
{
|
||||
.adr = 0x00033001FA424301ull,
|
||||
|
|
@ -235,48 +184,6 @@ static const struct snd_soc_acpi_adr_device cs35l56_2_lr_adr[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device cs35l56_1_3amp_adr[] = {
|
||||
{
|
||||
.adr = 0x00013001fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_1_endpoint,
|
||||
.name_prefix = "AMP1"
|
||||
},
|
||||
{
|
||||
.adr = 0x00013101fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_2_endpoint,
|
||||
.name_prefix = "AMP2"
|
||||
},
|
||||
{
|
||||
.adr = 0x00013201fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_3_endpoint,
|
||||
.name_prefix = "AMP3"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device cs35l56_3_3amp_adr[] = {
|
||||
{
|
||||
.adr = 0x00033301fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_4_endpoint,
|
||||
.name_prefix = "AMP4"
|
||||
},
|
||||
{
|
||||
.adr = 0x00033401fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_5_endpoint,
|
||||
.name_prefix = "AMP5"
|
||||
},
|
||||
{
|
||||
.adr = 0x00033501fa355601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_6_endpoint,
|
||||
.name_prefix = "AMP6"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = {
|
||||
{
|
||||
.adr = 0x000030025D071101ull,
|
||||
|
|
@ -408,25 +315,6 @@ static const struct snd_soc_acpi_link_adr ptl_cs42l43_agg_l3_cs35l56_l2[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr ptl_cs42l43_l2_cs35l56x6_l13[] = {
|
||||
{
|
||||
.mask = BIT(2),
|
||||
.num_adr = ARRAY_SIZE(cs42l43_2_adr),
|
||||
.adr_d = cs42l43_2_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(1),
|
||||
.num_adr = ARRAY_SIZE(cs35l56_1_3amp_adr),
|
||||
.adr_d = cs35l56_1_3amp_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(3),
|
||||
.num_adr = ARRAY_SIZE(cs35l56_3_3amp_adr),
|
||||
.adr_d = cs35l56_3_3amp_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr ptl_rt722_l0_rt1320_l23[] = {
|
||||
{
|
||||
.mask = BIT(0),
|
||||
|
|
@ -493,6 +381,20 @@ static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l3_rt1320_l12[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr ptl_sdw_rt713_vb_l3_rt1320_l1[] = {
|
||||
{
|
||||
.mask = BIT(3),
|
||||
.num_adr = ARRAY_SIZE(rt713_vb_3_adr),
|
||||
.adr_d = rt713_vb_3_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(1),
|
||||
.num_adr = ARRAY_SIZE(rt1320_1_group2_adr),
|
||||
.adr_d = rt1320_1_group2_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr ptl_sdw_rt712_vb_l2_rt1320_l1[] = {
|
||||
{
|
||||
.mask = BIT(2),
|
||||
|
|
@ -579,10 +481,11 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = {
|
|||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(1) | BIT(2) | BIT(3),
|
||||
.links = ptl_cs42l43_l2_cs35l56x6_l13,
|
||||
.link_mask = BIT(1) | BIT(3),
|
||||
.links = ptl_sdw_rt713_vb_l3_rt1320_l1,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-ptl-cs42l43-l2-cs35l56x6-l13.tplg",
|
||||
.sof_tplg_filename = "sof-ptl-rt713-l3-rt1320-l1.tplg",
|
||||
.get_function_tplg_files = sof_sdw_get_tplg_files,
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(0) | BIT(2) | BIT(3),
|
||||
|
|
@ -611,6 +514,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_ptl_sdw_machines[] = {
|
|||
.link_mask = BIT(2) | BIT(3),
|
||||
.links = ptl_cs42l43_agg_l3_cs35l56_l2,
|
||||
.drv_name = "sof_sdw",
|
||||
.machine_check = snd_soc_acpi_intel_no_function_topology,
|
||||
.sof_tplg_filename = "sof-ptl-cs42l43-agg-l3-cs35l56-l2.tplg",
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/soundwire/sdw_intel.h>
|
||||
#include <sound/sdca.h>
|
||||
#include <sound/soc-acpi.h>
|
||||
|
|
@ -37,6 +38,21 @@ bool snd_soc_acpi_intel_sdca_is_device_rt712_vb(void *arg)
|
|||
}
|
||||
EXPORT_SYMBOL_NS(snd_soc_acpi_intel_sdca_is_device_rt712_vb, "SND_SOC_ACPI_INTEL_SDCA_QUIRKS");
|
||||
|
||||
static const struct dmi_system_id function_topology_quirk_table[] = {
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Google"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
bool snd_soc_acpi_intel_no_function_topology(void *arg)
|
||||
{
|
||||
return !!dmi_check_system(function_topology_quirk_table);
|
||||
}
|
||||
EXPORT_SYMBOL_NS(snd_soc_acpi_intel_no_function_topology, "SND_SOC_ACPI_INTEL_SDCA_QUIRKS");
|
||||
|
||||
MODULE_DESCRIPTION("ASoC ACPI Intel SDCA quirks");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS("SND_SOC_SDCA");
|
||||
|
|
|
|||
|
|
@ -10,5 +10,6 @@
|
|||
#define _SND_SOC_ACPI_INTEL_SDCA_QUIRKS
|
||||
|
||||
bool snd_soc_acpi_intel_sdca_is_device_rt712_vb(void *arg);
|
||||
bool snd_soc_acpi_intel_no_function_topology(void *arg);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -497,7 +497,12 @@ static int q6apm_dai_pcm_new(struct snd_soc_component *component, struct snd_soc
|
|||
{
|
||||
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
|
||||
struct snd_pcm *pcm = rtd->pcm;
|
||||
int size = BUFFER_BYTES_MAX;
|
||||
/*
|
||||
* Allocate one extra page as a workaround for a DSP bug where 32-bit
|
||||
* address arithmetic can overflow when the buffer is placed near the
|
||||
* end of the addressable range.
|
||||
*/
|
||||
int size = BUFFER_BYTES_MAX + PAGE_SIZE;
|
||||
int graph_id, ret;
|
||||
struct snd_pcm_substream *substream;
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,8 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
|||
.dai_type = SOC_SDW_DAI_TYPE_MIC,
|
||||
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
|
||||
.rtd_init = asoc_sdw_rt_dmic_rtd_init,
|
||||
.quirk = SOC_SDW_CODEC_MIC,
|
||||
.quirk_exclude = true,
|
||||
},
|
||||
},
|
||||
.dai_num = 3,
|
||||
|
|
@ -501,6 +503,8 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
|||
.dai_type = SOC_SDW_DAI_TYPE_MIC,
|
||||
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_DMIC_DAI_ID},
|
||||
.rtd_init = asoc_sdw_rt_dmic_rtd_init,
|
||||
.quirk = SOC_SDW_CODEC_MIC,
|
||||
.quirk_exclude = true,
|
||||
},
|
||||
},
|
||||
.dai_num = 3,
|
||||
|
|
@ -1110,7 +1114,7 @@ int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
|||
struct asoc_sdw_codec_info *codec_info;
|
||||
struct snd_soc_dai *dai;
|
||||
struct sdw_slave *sdw_peripheral;
|
||||
const char *spk_components="";
|
||||
const char *spk_components = NULL;
|
||||
int dai_index;
|
||||
int ret;
|
||||
int i;
|
||||
|
|
@ -1193,7 +1197,7 @@ int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
|||
else
|
||||
component = codec_info->dais[dai_index].component_name;
|
||||
|
||||
if (strlen (spk_components) == 0)
|
||||
if (!spk_components)
|
||||
spk_components =
|
||||
devm_kasprintf(card->dev, GFP_KERNEL, "%s", component);
|
||||
else
|
||||
|
|
@ -1201,13 +1205,15 @@ int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
|||
spk_components =
|
||||
devm_kasprintf(card->dev, GFP_KERNEL,
|
||||
"%s+%s", spk_components, component);
|
||||
|
||||
if (!spk_components)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
codec_info->dais[dai_index].rtd_init_done = true;
|
||||
|
||||
}
|
||||
|
||||
if (strlen (spk_components) > 0) {
|
||||
if (spk_components) {
|
||||
/* Update card components for speaker components */
|
||||
card->components = devm_kasprintf(card->dev, GFP_KERNEL, "%s spk:%s",
|
||||
card->components, spk_components);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ int snd_soc_ret(const struct device *dev, int ret, const char *fmt, ...)
|
|||
vaf.va = &args;
|
||||
|
||||
dev_err(dev, "ASoC error (%d): %pV", ret, &vaf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ static int psp_send_cmd(struct acp_dev_data *adata, int cmd)
|
|||
{
|
||||
struct snd_sof_dev *sdev = adata->dev;
|
||||
int ret;
|
||||
u32 data;
|
||||
int data;
|
||||
|
||||
if (!cmd)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id,
|
|||
}
|
||||
|
||||
mux = clk_get_parent(dmic->fclk);
|
||||
if (IS_ERR(mux)) {
|
||||
if (!mux) {
|
||||
dev_err(dmic->dev, "can't get fck mux parent\n");
|
||||
clk_put(parent_clk);
|
||||
return -ENODEV;
|
||||
|
|
|
|||
|
|
@ -894,8 +894,9 @@ find_format_descriptor(struct usb_interface *interface)
|
|||
struct uac_format_type_i_discrete_descriptor *desc;
|
||||
|
||||
desc = (struct uac_format_type_i_discrete_descriptor *)extra;
|
||||
if (desc->bLength > extralen) {
|
||||
dev_err(&interface->dev, "descriptor overflow\n");
|
||||
if (desc->bLength < sizeof(struct usb_descriptor_header) ||
|
||||
desc->bLength > extralen) {
|
||||
dev_err(&interface->dev, "invalid descriptor length\n");
|
||||
return NULL;
|
||||
}
|
||||
if (desc->bLength == UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1) &&
|
||||
|
|
|
|||
|
|
@ -9187,12 +9187,15 @@ static long scarlett2_hwdep_write(struct snd_hwdep *hw,
|
|||
flash_size = private->flash_segment_blocks[segment_id] *
|
||||
SCARLETT2_FLASH_BLOCK_SIZE;
|
||||
|
||||
if (count < 0 || *offset < 0 || *offset + count >= flash_size)
|
||||
return -ENOSPC;
|
||||
if (count < 0 || *offset < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
if (*offset >= flash_size || count > flash_size - *offset)
|
||||
return -ENOSPC;
|
||||
|
||||
/* Limit the *req size to SCARLETT2_FLASH_RW_MAX */
|
||||
if (count > max_data_size)
|
||||
count = max_data_size;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user