mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 16:53:49 +00:00
sound fixes for 6.13-rc1
A collection of small fixes. Majority of changes are device-specific fixes and quirks, while there are a few core fixes to address regressions and corner cases spotted by fuzzers. - Fix of spinlock range that wrongly covered kvfree() call in rawmidi - Fix potential NULL dereference at PCM mmap - Fix incorrectly advertised MIDI 2.0 UMP Function Block info - Various ASoC AMD quirks and fixes - ASoC SOF Intel, Mediatek, HDMI-codec fixes - A few more quirks and TAS2781 codec fix for HD-audio - A couple of fixes for USB-audio for malicious USB descriptors -----BEGIN PGP SIGNATURE----- iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmdIeZUOHHRpd2FpQHN1 c2UuZGUACgkQLtJE4w1nLE9YNQ/+IHvY0LmY+7Xd1ZGWtf+Sucsn8FXcE5K654q5 RQwMbNNniSjXf8zyGfd05y/hVLWinaxYpM2m8DdGhIe/Fk2FYnU4itsChjv7TKW4 blqYoer1HHMUaXF03uiJGfBxadNtKS/y+b2RagNkirPDO9cpTnc8ITKmJkqeFc/I flxCoGdKGew2OybZnFjVbEvTP1rhO1kODI3wkgr85ru8zMcLYC/FSbs7prEnZ7LO gy88Km7/SVcAYIHgSFjSdRHuz0ZRdCekIObP94QuxTbJ1/7Js2pDX/JFtHOMUqgG p7GGaDofT6u6Ut+fUCqLC8D3f1uift+O+vn98+5KvnABO4z9sdhNBXabGE0vv/4U tw9jllXI97ylK0o6HSVIwYsRb5IOhjlxOO+rlAZDE6Y0ii2uhCCp0vVFr4xVQOh1 NeRqq1f4+TDxJSADzCUE/h1Hi9zepoK4GUQLasxGVCSxuIyiG8EW8U2/QZxhRSKP pYigpAIGbFHEzYEF+J+PXrfxgCEycv6jMq/RgkKbdbBiIYmnN6Q5lbSLpnDhTwjd qG0dBVX2KywHBlQm0nT2tKmyhoZu4c0gt0FnMWo9RAjyZON6YDXypc4KXon5a1kL kkgcDYQTccn4Klzvk1a3A+8Piz6B9UbJJ0fNjZiL0cp+awLQHg1GV+4bLp/iLQhm EivYr/U= =FLBb -----END PGP SIGNATURE----- Merge tag 'sound-fix-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound Pull sound fixes from Takashi Iwai: "A collection of small fixes. Majority of changes are device-specific fixes and quirks, while there are a few core fixes to address regressions and corner cases spotted by fuzzers. - Fix of spinlock range that wrongly covered kvfree() call in rawmidi - Fix potential NULL dereference at PCM mmap - Fix incorrectly advertised MIDI 2.0 UMP Function Block info - Various ASoC AMD quirks and fixes - ASoC SOF Intel, Mediatek, HDMI-codec fixes - A few more quirks and TAS2781 codec fix for HD-audio - A couple of fixes for USB-audio for malicious USB descriptors" * tag 'sound-fix-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (30 commits) ALSA: hda: improve bass speaker support for ASUS Zenbook UM5606WA ALSA: hda/realtek: Apply quirk for Medion E15433 ASoC: amd: yc: Add a quirk for microfone on Lenovo ThinkPad P14s Gen 5 21MES00B00 ASoC: SOF: ipc3-topology: Convert the topology pin index to ALH dai index ASoC: mediatek: Check num_codecs is not zero to avoid panic during probe ASoC: amd: yc: Fix for enabling DMIC on acp6x via _DSD entry ALSA: ump: Fix evaluation of MIDI 1.0 FB info ALSA: core: Fix possible NULL dereference caused by kunit_kzalloc() ALSA: hda: Show the codec quirk info at probing ALSA: asihpi: Remove unused variable ALSA: hda/realtek: Set PCBeep to default value for ALC274 ALSA: hda/tas2781: Add speaker id check for ASUS projects ALSA: hda/realtek: Update ALC225 depop procedure ALSA: hda/realtek: Enable speaker pins for Medion E15443 platform ALSA: hda/realtek: fix mute/micmute LEDs don't work for EliteBook X G1i ALSA: usb-audio: Fix out of bounds reads when finding clock sources ALSA: rawmidi: Fix kvfree() call in spinlock ALSA: hda/realtek: Fix Internal Speaker and Mic boost of Infinix Y4 Max ASoC: amd: yc: Add quirk for microphone on Lenovo Thinkpad T14s Gen 6 21M1CTO1WW ASoC: doc: dapm: Add location information for dapm-graph tool ...
This commit is contained in:
commit
517363b494
@ -42,7 +42,7 @@ If you are interested in the deep debugging of HD-audio, read the
|
||||
HD-audio specification at first. The specification is found on
|
||||
Intel's web page, for example:
|
||||
|
||||
* https://www.intel.com/standards/hdaudio/
|
||||
* https://www.intel.com/content/www/us/en/standards/high-definition-audio-specification.html
|
||||
|
||||
|
||||
HD-Audio Controller
|
||||
|
@ -35,6 +35,9 @@ The graph for the STM32MP1-DK1 sound card is shown in picture:
|
||||
:alt: Example DAPM graph
|
||||
:align: center
|
||||
|
||||
You can also generate compatible graph for your sound card using
|
||||
`tools/sound/dapm-graph` utility.
|
||||
|
||||
DAPM power domains
|
||||
==================
|
||||
|
||||
|
@ -156,6 +156,7 @@ struct tasdevice_priv {
|
||||
struct tasdevice_rca rcabin;
|
||||
struct calidata cali_data;
|
||||
struct tasdevice_fw *fmw;
|
||||
struct gpio_desc *speaker_id;
|
||||
struct gpio_desc *reset;
|
||||
struct mutex codec_lock;
|
||||
struct regmap *regmap;
|
||||
|
@ -180,7 +180,7 @@ static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
|
||||
|
||||
/**
|
||||
* snd_ac97_codec_driver_register - register an AC97 codec driver
|
||||
* @dev: AC97 driver codec to register
|
||||
* @drv: AC97 driver codec to register
|
||||
*
|
||||
* Register an AC97 codec driver to the ac97 bus driver, aka. the AC97 digital
|
||||
* controller.
|
||||
@ -196,7 +196,7 @@ EXPORT_SYMBOL_GPL(snd_ac97_codec_driver_register);
|
||||
|
||||
/**
|
||||
* snd_ac97_codec_driver_unregister - unregister an AC97 codec driver
|
||||
* @dev: AC97 codec driver to unregister
|
||||
* @drv: AC97 codec driver to unregister
|
||||
*
|
||||
* Unregister a previously registered ac97 codec driver.
|
||||
*/
|
||||
@ -338,6 +338,7 @@ static int ac97_add_adapter(struct ac97_controller *ac97_ctrl)
|
||||
* @dev: the device providing the ac97 DC function
|
||||
* @slots_available: mask of the ac97 codecs that can be scanned and probed
|
||||
* bit0 => codec 0, bit1 => codec 1 ... bit 3 => codec 3
|
||||
* @codecs_pdata: codec platform data
|
||||
*
|
||||
* Register a digital controller which can control up to 4 ac97 codecs. This is
|
||||
* the controller side of the AC97 AC-link, while the slave side are the codecs.
|
||||
|
@ -3813,9 +3813,11 @@ static vm_fault_t snd_pcm_mmap_data_fault(struct vm_fault *vmf)
|
||||
return VM_FAULT_SIGBUS;
|
||||
if (substream->ops->page)
|
||||
page = substream->ops->page(substream, offset);
|
||||
else if (!snd_pcm_get_dma_buf(substream))
|
||||
else if (!snd_pcm_get_dma_buf(substream)) {
|
||||
if (WARN_ON_ONCE(!runtime->dma_area))
|
||||
return VM_FAULT_SIGBUS;
|
||||
page = virt_to_page(runtime->dma_area + offset);
|
||||
else
|
||||
} else
|
||||
page = snd_sgbuf_get_page(snd_pcm_get_dma_buf(substream), offset);
|
||||
if (!page)
|
||||
return VM_FAULT_SIGBUS;
|
||||
|
@ -724,8 +724,9 @@ static int resize_runtime_buffer(struct snd_rawmidi_substream *substream,
|
||||
newbuf = kvzalloc(params->buffer_size, GFP_KERNEL);
|
||||
if (!newbuf)
|
||||
return -ENOMEM;
|
||||
guard(spinlock_irq)(&substream->lock);
|
||||
spin_lock_irq(&substream->lock);
|
||||
if (runtime->buffer_ref) {
|
||||
spin_unlock_irq(&substream->lock);
|
||||
kvfree(newbuf);
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -733,6 +734,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_substream *substream,
|
||||
runtime->buffer = newbuf;
|
||||
runtime->buffer_size = params->buffer_size;
|
||||
__reset_runtime_ptrs(runtime, is_input);
|
||||
spin_unlock_irq(&substream->lock);
|
||||
kvfree(oldbuf);
|
||||
}
|
||||
runtime->avail_min = params->avail_min;
|
||||
|
@ -172,6 +172,7 @@ static void test_format_fill_silence(struct kunit *test)
|
||||
u32 i, j;
|
||||
|
||||
buffer = kunit_kzalloc(test, SILENCE_BUFFER_SIZE, GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(buf_samples); i++) {
|
||||
for (j = 0; j < ARRAY_SIZE(valid_fmt); j++)
|
||||
@ -208,8 +209,12 @@ static void test_playback_avail(struct kunit *test)
|
||||
struct snd_pcm_runtime *r = kunit_kzalloc(test, sizeof(*r), GFP_KERNEL);
|
||||
u32 i;
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r);
|
||||
|
||||
r->status = kunit_kzalloc(test, sizeof(*r->status), GFP_KERNEL);
|
||||
r->control = kunit_kzalloc(test, sizeof(*r->control), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r->status);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r->control);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(p_avail_data); i++) {
|
||||
r->buffer_size = p_avail_data[i].buffer_size;
|
||||
@ -232,8 +237,12 @@ static void test_capture_avail(struct kunit *test)
|
||||
struct snd_pcm_runtime *r = kunit_kzalloc(test, sizeof(*r), GFP_KERNEL);
|
||||
u32 i;
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r);
|
||||
|
||||
r->status = kunit_kzalloc(test, sizeof(*r->status), GFP_KERNEL);
|
||||
r->control = kunit_kzalloc(test, sizeof(*r->control), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r->status);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, r->control);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(c_avail_data); i++) {
|
||||
r->buffer_size = c_avail_data[i].buffer_size;
|
||||
@ -247,6 +256,7 @@ static void test_capture_avail(struct kunit *test)
|
||||
static void test_card_set_id(struct kunit *test)
|
||||
{
|
||||
struct snd_card *card = kunit_kzalloc(test, sizeof(*card), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, card);
|
||||
|
||||
snd_card_set_id(card, VALID_NAME);
|
||||
KUNIT_EXPECT_STREQ(test, card->id, VALID_NAME);
|
||||
@ -280,6 +290,7 @@ static void test_pcm_format_name(struct kunit *test)
|
||||
static void test_card_add_component(struct kunit *test)
|
||||
{
|
||||
struct snd_card *card = kunit_kzalloc(test, sizeof(*card), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, card);
|
||||
|
||||
snd_component_add(card, TEST_FIRST_COMPONENT);
|
||||
KUNIT_ASSERT_STREQ(test, card->components, TEST_FIRST_COMPONENT);
|
||||
|
@ -788,7 +788,10 @@ static void fill_fb_info(struct snd_ump_endpoint *ump,
|
||||
info->ui_hint = buf->fb_info.ui_hint;
|
||||
info->first_group = buf->fb_info.first_group;
|
||||
info->num_groups = buf->fb_info.num_groups;
|
||||
info->flags = buf->fb_info.midi_10;
|
||||
if (buf->fb_info.midi_10 < 2)
|
||||
info->flags = buf->fb_info.midi_10;
|
||||
else
|
||||
info->flags = SNDRV_UMP_BLOCK_IS_MIDI1 | SNDRV_UMP_BLOCK_IS_LOWSPEED;
|
||||
info->active = buf->fb_info.active;
|
||||
info->midi_ci_version = buf->fb_info.midi_ci_version;
|
||||
info->sysex8_streams = buf->fb_info.sysex8_streams;
|
||||
|
@ -464,7 +464,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
|
||||
hpi_stream_get_info_ex(dpcm->h_stream, NULL,
|
||||
&dpcm->hpi_buffer_attached, NULL, NULL, NULL);
|
||||
}
|
||||
bytes_per_sec = params_rate(params) * params_channels(params);
|
||||
|
@ -933,6 +933,7 @@ void snd_hda_pick_pin_fixup(struct hda_codec *codec,
|
||||
bool match_all_pins)
|
||||
{
|
||||
const struct snd_hda_pin_quirk *pq;
|
||||
const char *name = NULL;
|
||||
|
||||
if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
|
||||
return;
|
||||
@ -946,9 +947,10 @@ void snd_hda_pick_pin_fixup(struct hda_codec *codec,
|
||||
codec->fixup_id = pq->value;
|
||||
#ifdef CONFIG_SND_DEBUG_VERBOSE
|
||||
codec->fixup_name = pq->name;
|
||||
codec_dbg(codec, "%s: picked fixup %s (pin match)\n",
|
||||
codec->core.chip_name, codec->fixup_name);
|
||||
name = pq->name;
|
||||
#endif
|
||||
codec_info(codec, "%s: picked fixup %s (pin match)\n",
|
||||
codec->core.chip_name, name ? name : "");
|
||||
codec->fixup_list = fixlist;
|
||||
return;
|
||||
}
|
||||
@ -1015,8 +1017,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||
if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
|
||||
id = HDA_FIXUP_ID_NO_FIXUP;
|
||||
fixlist = NULL;
|
||||
codec_dbg(codec, "%s: picked no fixup (nofixup specified)\n",
|
||||
codec->core.chip_name);
|
||||
codec_info(codec, "%s: picked no fixup (nofixup specified)\n",
|
||||
codec->core.chip_name);
|
||||
goto found;
|
||||
}
|
||||
|
||||
@ -1026,8 +1028,8 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||
if (!strcmp(codec->modelname, models->name)) {
|
||||
id = models->id;
|
||||
name = models->name;
|
||||
codec_dbg(codec, "%s: picked fixup %s (model specified)\n",
|
||||
codec->core.chip_name, codec->fixup_name);
|
||||
codec_info(codec, "%s: picked fixup %s (model specified)\n",
|
||||
codec->core.chip_name, name);
|
||||
goto found;
|
||||
}
|
||||
models++;
|
||||
@ -1085,9 +1087,9 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||
#ifdef CONFIG_SND_DEBUG_VERBOSE
|
||||
name = q->name;
|
||||
#endif
|
||||
codec_dbg(codec, "%s: picked fixup %s for %s %04x:%04x\n",
|
||||
codec->core.chip_name, name ? name : "",
|
||||
type, q->subvendor, q->subdevice);
|
||||
codec_info(codec, "%s: picked fixup %s for %s %04x:%04x\n",
|
||||
codec->core.chip_name, name ? name : "",
|
||||
type, q->subvendor, q->subdevice);
|
||||
found:
|
||||
codec->fixup_id = id;
|
||||
codec->fixup_list = fixlist;
|
||||
|
@ -473,6 +473,8 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
|
||||
break;
|
||||
case 0x10ec0234:
|
||||
case 0x10ec0274:
|
||||
alc_write_coef_idx(codec, 0x6e, 0x0c25);
|
||||
fallthrough;
|
||||
case 0x10ec0294:
|
||||
case 0x10ec0700:
|
||||
case 0x10ec0701:
|
||||
@ -3613,25 +3615,22 @@ static void alc256_init(struct hda_codec *codec)
|
||||
|
||||
hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
|
||||
|
||||
if (hp_pin_sense)
|
||||
if (hp_pin_sense) {
|
||||
msleep(2);
|
||||
alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
|
||||
|
||||
alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
|
||||
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
|
||||
|
||||
if (hp_pin_sense || spec->ultra_low_power)
|
||||
msleep(85);
|
||||
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
|
||||
if (hp_pin_sense || spec->ultra_low_power)
|
||||
msleep(100);
|
||||
msleep(75);
|
||||
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
|
||||
|
||||
msleep(75);
|
||||
alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
|
||||
}
|
||||
alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
|
||||
alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
|
||||
alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 1 << 15); /* Clear bit */
|
||||
alc_update_coefex_idx(codec, 0x53, 0x02, 0x8000, 0 << 15);
|
||||
/*
|
||||
@ -3655,29 +3654,28 @@ static void alc256_shutup(struct hda_codec *codec)
|
||||
alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
|
||||
hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
|
||||
|
||||
if (hp_pin_sense)
|
||||
if (hp_pin_sense) {
|
||||
msleep(2);
|
||||
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
|
||||
|
||||
if (hp_pin_sense || spec->ultra_low_power)
|
||||
msleep(85);
|
||||
msleep(75);
|
||||
|
||||
/* 3k pull low control for Headset jack. */
|
||||
/* NOTE: call this before clearing the pin, otherwise codec stalls */
|
||||
/* If disable 3k pulldown control for alc257, the Mic detection will not work correctly
|
||||
* when booting with headset plugged. So skip setting it for the codec alc257
|
||||
*/
|
||||
if (spec->en_3kpull_low)
|
||||
alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
|
||||
if (spec->en_3kpull_low)
|
||||
alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
|
||||
|
||||
if (!spec->no_shutup_pins)
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
if (!spec->no_shutup_pins)
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
|
||||
|
||||
if (hp_pin_sense || spec->ultra_low_power)
|
||||
msleep(100);
|
||||
msleep(75);
|
||||
}
|
||||
|
||||
alc_auto_setup_eapd(codec, false);
|
||||
alc_shutup_pins(codec);
|
||||
@ -3772,33 +3770,28 @@ static void alc225_init(struct hda_codec *codec)
|
||||
hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
|
||||
hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
|
||||
|
||||
if (hp1_pin_sense || hp2_pin_sense)
|
||||
if (hp1_pin_sense || hp2_pin_sense) {
|
||||
msleep(2);
|
||||
alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
|
||||
|
||||
alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */
|
||||
if (hp1_pin_sense)
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
if (hp2_pin_sense)
|
||||
snd_hda_codec_write(codec, 0x16, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
msleep(75);
|
||||
|
||||
if (hp1_pin_sense || spec->ultra_low_power)
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
|
||||
if (hp2_pin_sense)
|
||||
snd_hda_codec_write(codec, 0x16, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
|
||||
if (hp1_pin_sense)
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
|
||||
if (hp2_pin_sense)
|
||||
snd_hda_codec_write(codec, 0x16, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
|
||||
|
||||
if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
|
||||
msleep(85);
|
||||
|
||||
if (hp1_pin_sense || spec->ultra_low_power)
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
if (hp2_pin_sense)
|
||||
snd_hda_codec_write(codec, 0x16, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
|
||||
if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
|
||||
msleep(100);
|
||||
|
||||
alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
|
||||
alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
|
||||
msleep(75);
|
||||
alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */
|
||||
}
|
||||
}
|
||||
|
||||
static void alc225_shutup(struct hda_codec *codec)
|
||||
@ -3810,36 +3803,35 @@ static void alc225_shutup(struct hda_codec *codec)
|
||||
if (!hp_pin)
|
||||
hp_pin = 0x21;
|
||||
|
||||
alc_disable_headset_jack_key(codec);
|
||||
/* 3k pull low control for Headset jack. */
|
||||
alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
|
||||
|
||||
hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin);
|
||||
hp2_pin_sense = snd_hda_jack_detect(codec, 0x16);
|
||||
|
||||
if (hp1_pin_sense || hp2_pin_sense)
|
||||
if (hp1_pin_sense || hp2_pin_sense) {
|
||||
alc_disable_headset_jack_key(codec);
|
||||
/* 3k pull low control for Headset jack. */
|
||||
alc_update_coef_idx(codec, 0x4a, 0, 3 << 10);
|
||||
msleep(2);
|
||||
|
||||
if (hp1_pin_sense || spec->ultra_low_power)
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
|
||||
if (hp2_pin_sense)
|
||||
snd_hda_codec_write(codec, 0x16, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
|
||||
if (hp1_pin_sense)
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
|
||||
if (hp2_pin_sense)
|
||||
snd_hda_codec_write(codec, 0x16, 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
|
||||
|
||||
if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
|
||||
msleep(85);
|
||||
msleep(75);
|
||||
|
||||
if (hp1_pin_sense || spec->ultra_low_power)
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
|
||||
if (hp2_pin_sense)
|
||||
snd_hda_codec_write(codec, 0x16, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
|
||||
|
||||
if (hp1_pin_sense || hp2_pin_sense || spec->ultra_low_power)
|
||||
msleep(100);
|
||||
if (hp1_pin_sense)
|
||||
snd_hda_codec_write(codec, hp_pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
|
||||
if (hp2_pin_sense)
|
||||
snd_hda_codec_write(codec, 0x16, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
|
||||
|
||||
msleep(75);
|
||||
alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
|
||||
alc_enable_headset_jack_key(codec);
|
||||
}
|
||||
alc_auto_setup_eapd(codec, false);
|
||||
alc_shutup_pins(codec);
|
||||
if (spec->ultra_low_power) {
|
||||
@ -3850,9 +3842,6 @@ static void alc225_shutup(struct hda_codec *codec)
|
||||
alc_update_coef_idx(codec, 0x4a, 3<<4, 2<<4);
|
||||
msleep(30);
|
||||
}
|
||||
|
||||
alc_update_coef_idx(codec, 0x4a, 3 << 10, 0);
|
||||
alc_enable_headset_jack_key(codec);
|
||||
}
|
||||
|
||||
static void alc_default_init(struct hda_codec *codec)
|
||||
@ -6502,6 +6491,16 @@ static void alc285_fixup_speaker2_to_dac1(struct hda_codec *codec,
|
||||
}
|
||||
}
|
||||
|
||||
/* disable DAC3 (0x06) selection on NID 0x15 - share Speaker/Bass Speaker DAC 0x03 */
|
||||
static void alc294_fixup_bass_speaker_15(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
||||
static const hda_nid_t conn[] = { 0x02, 0x03 };
|
||||
snd_hda_override_conn_list(codec, 0x15, ARRAY_SIZE(conn), conn);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hook to update amp GPIO4 for automute */
|
||||
static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
|
||||
struct hda_jack_callback *jack)
|
||||
@ -7559,6 +7558,7 @@ enum {
|
||||
ALC269_FIXUP_THINKPAD_ACPI,
|
||||
ALC269_FIXUP_DMIC_THINKPAD_ACPI,
|
||||
ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13,
|
||||
ALC269VC_FIXUP_INFINIX_Y4_MAX,
|
||||
ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO,
|
||||
ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
|
||||
ALC255_FIXUP_ASUS_MIC_NO_PRESENCE,
|
||||
@ -7782,6 +7782,8 @@ enum {
|
||||
ALC256_FIXUP_CHROME_BOOK,
|
||||
ALC245_FIXUP_CLEVO_NOISY_MIC,
|
||||
ALC269_FIXUP_VAIO_VJFH52_MIC_NO_PRESENCE,
|
||||
ALC233_FIXUP_MEDION_MTL_SPK,
|
||||
ALC294_FIXUP_BASS_SPEAKER_15,
|
||||
};
|
||||
|
||||
/* A special fixup for Lenovo C940 and Yoga Duet 7;
|
||||
@ -7945,6 +7947,15 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
|
||||
},
|
||||
[ALC269VC_FIXUP_INFINIX_Y4_MAX] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x1b, 0x90170150 }, /* use as internal speaker */
|
||||
{ }
|
||||
},
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
|
||||
},
|
||||
[ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
@ -10074,6 +10085,17 @@ static const struct hda_fixup alc269_fixups[] = {
|
||||
.chained = true,
|
||||
.chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
|
||||
},
|
||||
[ALC233_FIXUP_MEDION_MTL_SPK] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x1b, 0x90170110 },
|
||||
{ }
|
||||
},
|
||||
},
|
||||
[ALC294_FIXUP_BASS_SPEAKER_15] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc294_fixup_bass_speaker_15,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
@ -10499,6 +10521,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x8cdf, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8ce0, "HP SnowWhite", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED),
|
||||
SND_PCI_QUIRK(0x103c, 0x8d84, "HP EliteBook X G1i", ALC285_FIXUP_HP_GPIO_LED),
|
||||
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, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||
@ -10582,6 +10605,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401),
|
||||
SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
|
||||
SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1df3, "ASUS UM5606WA", ALC294_FIXUP_BASS_SPEAKER_15),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
|
||||
SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2),
|
||||
@ -10943,7 +10967,10 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
|
||||
SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13),
|
||||
SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),
|
||||
SND_PCI_QUIRK(0x2782, 0x1701, "Infinix Y4 Max", ALC269VC_FIXUP_INFINIX_Y4_MAX),
|
||||
SND_PCI_QUIRK(0x2782, 0x1705, "MEDION E15433", ALC269VC_FIXUP_INFINIX_Y4_MAX),
|
||||
SND_PCI_QUIRK(0x2782, 0x1707, "Vaio VJFE-ADL", ALC298_FIXUP_SPK_VOLUME),
|
||||
SND_PCI_QUIRK(0x2782, 0x4900, "MEDION E15443", ALC233_FIXUP_MEDION_MTL_SPK),
|
||||
SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC),
|
||||
SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
|
||||
SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10),
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/hda_codec.h>
|
||||
@ -110,10 +111,20 @@ static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct acpi_gpio_params speakerid_gpios = { 0, 0, false };
|
||||
|
||||
static const struct acpi_gpio_mapping tas2781_speaker_id_gpios[] = {
|
||||
{ "speakerid-gpios", &speakerid_gpios, 1 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
struct device *physdev;
|
||||
LIST_HEAD(resources);
|
||||
const char *sub;
|
||||
uint32_t subid;
|
||||
int ret;
|
||||
|
||||
adev = acpi_dev_get_first_match_dev(hid, NULL, -1);
|
||||
@ -123,18 +134,45 @@ static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
physdev = get_device(acpi_get_first_physical_node(adev));
|
||||
ret = acpi_dev_get_resources(adev, &resources, tas2781_get_i2c_res, p);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
dev_err(p->dev, "Failed to get ACPI resource.\n");
|
||||
goto err;
|
||||
}
|
||||
sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev));
|
||||
if (IS_ERR(sub)) {
|
||||
dev_err(p->dev, "Failed to get SUBSYS ID.\n");
|
||||
goto err;
|
||||
}
|
||||
/* Speaker id was needed for ASUS projects. */
|
||||
ret = kstrtou32(sub, 16, &subid);
|
||||
if (!ret && upper_16_bits(subid) == PCI_VENDOR_ID_ASUSTEK) {
|
||||
ret = devm_acpi_dev_add_driver_gpios(p->dev,
|
||||
tas2781_speaker_id_gpios);
|
||||
if (ret < 0)
|
||||
dev_err(p->dev, "Failed to add driver gpio %d.\n",
|
||||
ret);
|
||||
p->speaker_id = devm_gpiod_get(p->dev, "speakerid", GPIOD_IN);
|
||||
if (IS_ERR(p->speaker_id)) {
|
||||
dev_err(p->dev, "Failed to get Speaker id.\n");
|
||||
ret = PTR_ERR(p->speaker_id);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
p->speaker_id = NULL;
|
||||
}
|
||||
|
||||
acpi_dev_free_resource_list(&resources);
|
||||
strscpy(p->dev_name, hid, sizeof(p->dev_name));
|
||||
put_device(physdev);
|
||||
acpi_dev_put(adev);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_err(p->dev, "read acpi error, ret: %d\n", ret);
|
||||
put_device(physdev);
|
||||
acpi_dev_put(adev);
|
||||
|
||||
return ret;
|
||||
@ -615,7 +653,7 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
|
||||
struct tasdevice_priv *tas_priv = context;
|
||||
struct tas2781_hda *tas_hda = dev_get_drvdata(tas_priv->dev);
|
||||
struct hda_codec *codec = tas_priv->codec;
|
||||
int i, ret;
|
||||
int i, ret, spk_id;
|
||||
|
||||
pm_runtime_get_sync(tas_priv->dev);
|
||||
mutex_lock(&tas_priv->codec_lock);
|
||||
@ -648,8 +686,25 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
|
||||
tasdevice_dsp_remove(tas_priv);
|
||||
|
||||
tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING;
|
||||
scnprintf(tas_priv->coef_binaryname, 64, "TAS2XXX%04X.bin",
|
||||
codec->core.subsystem_id & 0xffff);
|
||||
if (tas_priv->speaker_id != NULL) {
|
||||
// Speaker id need to be checked for ASUS only.
|
||||
spk_id = gpiod_get_value(tas_priv->speaker_id);
|
||||
if (spk_id < 0) {
|
||||
// Speaker id is not valid, use default.
|
||||
dev_dbg(tas_priv->dev, "Wrong spk_id = %d\n", spk_id);
|
||||
spk_id = 0;
|
||||
}
|
||||
snprintf(tas_priv->coef_binaryname,
|
||||
sizeof(tas_priv->coef_binaryname),
|
||||
"TAS2XXX%04X%d.bin",
|
||||
lower_16_bits(codec->core.subsystem_id),
|
||||
spk_id);
|
||||
} else {
|
||||
snprintf(tas_priv->coef_binaryname,
|
||||
sizeof(tas_priv->coef_binaryname),
|
||||
"TAS2XXX%04X.bin",
|
||||
lower_16_bits(codec->core.subsystem_id));
|
||||
}
|
||||
ret = tasdevice_dsp_parser(tas_priv);
|
||||
if (ret) {
|
||||
dev_err(tas_priv->dev, "dspfw load %s error\n",
|
||||
|
@ -163,6 +163,7 @@ config SND_SOC_AMD_SOUNDWIRE
|
||||
config SND_SOC_AMD_PS
|
||||
tristate "AMD Audio Coprocessor-v6.3 Pink Sardine support"
|
||||
select SND_SOC_AMD_SOUNDWIRE_LINK_BASELINE
|
||||
select SND_SOC_ACPI_AMD_MATCH
|
||||
depends on X86 && PCI && ACPI
|
||||
help
|
||||
This option enables Audio Coprocessor i.e ACP v6.3 support on
|
||||
|
@ -220,6 +220,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21J6"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21M1"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
@ -241,6 +248,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21M5"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "21ME"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
@ -409,6 +423,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Xiaomi Book Pro 14 2022"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Redmi G 2022"),
|
||||
}
|
||||
},
|
||||
{
|
||||
.driver_data = &acp6x_card,
|
||||
.matches = {
|
||||
@ -537,8 +558,14 @@ static int acp6x_probe(struct platform_device *pdev)
|
||||
struct acp6x_pdm *machine = NULL;
|
||||
struct snd_soc_card *card;
|
||||
struct acpi_device *adev;
|
||||
acpi_handle handle;
|
||||
acpi_integer dmic_status;
|
||||
int ret;
|
||||
bool is_dmic_enable, wov_en;
|
||||
|
||||
/* IF WOV entry not found, enable dmic based on AcpDmicConnected entry*/
|
||||
is_dmic_enable = false;
|
||||
wov_en = true;
|
||||
/* check the parent device's firmware node has _DSD or not */
|
||||
adev = ACPI_COMPANION(pdev->dev.parent);
|
||||
if (adev) {
|
||||
@ -546,9 +573,19 @@ static int acp6x_probe(struct platform_device *pdev)
|
||||
|
||||
if (!acpi_dev_get_property(adev, "AcpDmicConnected", ACPI_TYPE_INTEGER, &obj) &&
|
||||
obj->integer.value == 1)
|
||||
platform_set_drvdata(pdev, &acp6x_card);
|
||||
is_dmic_enable = true;
|
||||
}
|
||||
|
||||
handle = ACPI_HANDLE(pdev->dev.parent);
|
||||
ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status);
|
||||
if (!ACPI_FAILURE(ret))
|
||||
wov_en = dmic_status;
|
||||
|
||||
if (is_dmic_enable && wov_en)
|
||||
platform_set_drvdata(pdev, &acp6x_card);
|
||||
else
|
||||
return 0;
|
||||
|
||||
/* check for any DMI overrides */
|
||||
dmi_id = dmi_first_match(yc_acp_quirk_table);
|
||||
if (dmi_id)
|
||||
|
@ -616,7 +616,7 @@ static int mca_fe_hw_params(struct snd_pcm_substream *substream,
|
||||
tdm_slot_width = 32;
|
||||
|
||||
if (tdm_slot_width < params_width(params)) {
|
||||
dev_err(dev, "TDM slots too narrow (tdm=%d params=%d)\n",
|
||||
dev_err(dev, "TDM slots too narrow (tdm=%u params=%d)\n",
|
||||
tdm_slot_width, params_width(params));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -274,6 +274,9 @@ static int imx_audmix_probe(struct platform_device *pdev)
|
||||
/* Add AUDMIX Backend */
|
||||
be_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
||||
"audmix-%d", i);
|
||||
if (!be_name)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->dai[num_dai + i].cpus = &dlc[1];
|
||||
priv->dai[num_dai + i].codecs = &snd_soc_dummy_dlc;
|
||||
|
||||
|
@ -1277,10 +1277,12 @@ static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data,
|
||||
|
||||
for_each_card_prelinks(card, i, dai_link) {
|
||||
if (strcmp(dai_link->name, "DPTX_BE") == 0) {
|
||||
if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
|
||||
if (dai_link->num_codecs &&
|
||||
strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
|
||||
dai_link->init = mt8188_dptx_codec_init;
|
||||
} else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
|
||||
if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
|
||||
if (dai_link->num_codecs &&
|
||||
strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
|
||||
dai_link->init = mt8188_hdmi_codec_init;
|
||||
} else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 ||
|
||||
strcmp(dai_link->name, "UL_SRC_BE") == 0) {
|
||||
@ -1292,6 +1294,9 @@ static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data,
|
||||
strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 ||
|
||||
strcmp(dai_link->name, "ETDM1_IN_BE") == 0 ||
|
||||
strcmp(dai_link->name, "ETDM2_IN_BE") == 0) {
|
||||
if (!dai_link->num_codecs)
|
||||
continue;
|
||||
|
||||
if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) {
|
||||
/*
|
||||
* The TDM protocol settings with fixed 4 slots are defined in
|
||||
|
@ -1091,7 +1091,7 @@ static int mt8192_mt6359_legacy_probe(struct mtk_soc_card_data *soc_card_data)
|
||||
dai_link->ignore = 0;
|
||||
}
|
||||
|
||||
if (dai_link->num_codecs && dai_link->codecs[0].dai_name &&
|
||||
if (dai_link->num_codecs &&
|
||||
strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0)
|
||||
dai_link->ops = &mt8192_rt1015_i2s_ops;
|
||||
}
|
||||
@ -1119,7 +1119,7 @@ static int mt8192_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data,
|
||||
int i;
|
||||
|
||||
for_each_card_prelinks(card, i, dai_link)
|
||||
if (dai_link->num_codecs && dai_link->codecs[0].dai_name &&
|
||||
if (dai_link->num_codecs &&
|
||||
strcmp(dai_link->codecs[0].dai_name, RT1015_CODEC_DAI) == 0)
|
||||
dai_link->ops = &mt8192_rt1015_i2s_ops;
|
||||
}
|
||||
|
@ -1378,10 +1378,12 @@ static int mt8195_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data,
|
||||
|
||||
for_each_card_prelinks(card, i, dai_link) {
|
||||
if (strcmp(dai_link->name, "DPTX_BE") == 0) {
|
||||
if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
|
||||
if (dai_link->num_codecs &&
|
||||
strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
|
||||
dai_link->init = mt8195_dptx_codec_init;
|
||||
} else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
|
||||
if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
|
||||
if (dai_link->num_codecs &&
|
||||
strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))
|
||||
dai_link->init = mt8195_hdmi_codec_init;
|
||||
} else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 ||
|
||||
strcmp(dai_link->name, "UL_SRC1_BE") == 0 ||
|
||||
@ -1394,6 +1396,9 @@ static int mt8195_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data,
|
||||
strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 ||
|
||||
strcmp(dai_link->name, "ETDM1_IN_BE") == 0 ||
|
||||
strcmp(dai_link->name, "ETDM2_IN_BE") == 0) {
|
||||
if (!dai_link->num_codecs)
|
||||
continue;
|
||||
|
||||
if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) {
|
||||
if (!(codec_init & MAX98390_CODEC_INIT)) {
|
||||
dai_link->init = mt8195_max98390_init;
|
||||
|
@ -20,6 +20,9 @@
|
||||
/* size of tplg ABI in bytes */
|
||||
#define SOF_IPC3_TPLG_ABI_SIZE 3
|
||||
|
||||
/* Base of SOF_DAI_INTEL_ALH, this should be aligned with SOC_SDW_INTEL_BIDIR_PDI_BASE */
|
||||
#define INTEL_ALH_DAI_INDEX_BASE 2
|
||||
|
||||
struct sof_widget_data {
|
||||
int ctrl_type;
|
||||
int ipc_cmd;
|
||||
@ -1594,6 +1597,17 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget)
|
||||
if (ret < 0)
|
||||
goto free;
|
||||
|
||||
/* Subtract the base to match the FW dai index. */
|
||||
if (comp_dai->type == SOF_DAI_INTEL_ALH) {
|
||||
if (comp_dai->dai_index < INTEL_ALH_DAI_INDEX_BASE) {
|
||||
dev_err(sdev->dev,
|
||||
"Invalid ALH dai index %d, only Pin numbers >= %d can be used\n",
|
||||
comp_dai->dai_index, INTEL_ALH_DAI_INDEX_BASE);
|
||||
return -EINVAL;
|
||||
}
|
||||
comp_dai->dai_index -= INTEL_ALH_DAI_INDEX_BASE;
|
||||
}
|
||||
|
||||
dev_dbg(scomp->dev, "dai %s: type %d index %d\n",
|
||||
swidget->widget->name, comp_dai->type, comp_dai->dai_index);
|
||||
sof_dbg_comp_config(scomp, &comp_dai->config);
|
||||
@ -2167,8 +2181,16 @@ static int sof_ipc3_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *
|
||||
case SOF_DAI_INTEL_ALH:
|
||||
if (data) {
|
||||
/* save the dai_index during hw_params and reuse it for hw_free */
|
||||
if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS)
|
||||
config->dai_index = data->dai_index;
|
||||
if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) {
|
||||
/* Subtract the base to match the FW dai index. */
|
||||
if (data->dai_index < INTEL_ALH_DAI_INDEX_BASE) {
|
||||
dev_err(sdev->dev,
|
||||
"Invalid ALH dai index %d, only Pin numbers >= %d can be used\n",
|
||||
config->dai_index, INTEL_ALH_DAI_INDEX_BASE);
|
||||
return -EINVAL;
|
||||
}
|
||||
config->dai_index = data->dai_index - INTEL_ALH_DAI_INDEX_BASE;
|
||||
}
|
||||
config->alh.stream_id = data->dai_data;
|
||||
}
|
||||
break;
|
||||
|
@ -36,6 +36,12 @@ union uac23_clock_multiplier_desc {
|
||||
struct uac_clock_multiplier_descriptor v3;
|
||||
};
|
||||
|
||||
/* check whether the descriptor bLength has the minimal length */
|
||||
#define DESC_LENGTH_CHECK(p, proto) \
|
||||
((proto) == UAC_VERSION_3 ? \
|
||||
((p)->v3.bLength >= sizeof((p)->v3)) : \
|
||||
((p)->v2.bLength >= sizeof((p)->v2)))
|
||||
|
||||
#define GET_VAL(p, proto, field) \
|
||||
((proto) == UAC_VERSION_3 ? (p)->v3.field : (p)->v2.field)
|
||||
|
||||
@ -58,6 +64,8 @@ static bool validate_clock_source(void *p, int id, int proto)
|
||||
{
|
||||
union uac23_clock_source_desc *cs = p;
|
||||
|
||||
if (!DESC_LENGTH_CHECK(cs, proto))
|
||||
return false;
|
||||
return GET_VAL(cs, proto, bClockID) == id;
|
||||
}
|
||||
|
||||
@ -65,13 +73,27 @@ static bool validate_clock_selector(void *p, int id, int proto)
|
||||
{
|
||||
union uac23_clock_selector_desc *cs = p;
|
||||
|
||||
return GET_VAL(cs, proto, bClockID) == id;
|
||||
if (!DESC_LENGTH_CHECK(cs, proto))
|
||||
return false;
|
||||
if (GET_VAL(cs, proto, bClockID) != id)
|
||||
return false;
|
||||
/* additional length check for baCSourceID array (in bNrInPins size)
|
||||
* and two more fields (which sizes depend on the protocol)
|
||||
*/
|
||||
if (proto == UAC_VERSION_3)
|
||||
return cs->v3.bLength >= sizeof(cs->v3) + cs->v3.bNrInPins +
|
||||
4 /* bmControls */ + 2 /* wCSelectorDescrStr */;
|
||||
else
|
||||
return cs->v2.bLength >= sizeof(cs->v2) + cs->v2.bNrInPins +
|
||||
1 /* bmControls */ + 1 /* iClockSelector */;
|
||||
}
|
||||
|
||||
static bool validate_clock_multiplier(void *p, int id, int proto)
|
||||
{
|
||||
union uac23_clock_multiplier_desc *cs = p;
|
||||
|
||||
if (!DESC_LENGTH_CHECK(cs, proto))
|
||||
return false;
|
||||
return GET_VAL(cs, proto, bClockID) == id;
|
||||
}
|
||||
|
||||
|
@ -555,6 +555,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
|
||||
static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
|
||||
{
|
||||
struct usb_host_config *config = dev->actconfig;
|
||||
struct usb_device_descriptor new_device_descriptor;
|
||||
int err;
|
||||
|
||||
if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
|
||||
@ -566,10 +567,14 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac
|
||||
if (err < 0)
|
||||
dev_dbg(&dev->dev, "error sending boot message: %d\n", err);
|
||||
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
|
||||
&dev->descriptor, sizeof(dev->descriptor));
|
||||
config = dev->actconfig;
|
||||
&new_device_descriptor, sizeof(new_device_descriptor));
|
||||
if (err < 0)
|
||||
dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
|
||||
if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations)
|
||||
dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n",
|
||||
new_device_descriptor.bNumConfigurations);
|
||||
else
|
||||
memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor));
|
||||
err = usb_reset_configuration(dev);
|
||||
if (err < 0)
|
||||
dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
|
||||
@ -901,6 +906,7 @@ static void mbox2_setup_48_24_magic(struct usb_device *dev)
|
||||
static int snd_usb_mbox2_boot_quirk(struct usb_device *dev)
|
||||
{
|
||||
struct usb_host_config *config = dev->actconfig;
|
||||
struct usb_device_descriptor new_device_descriptor;
|
||||
int err;
|
||||
u8 bootresponse[0x12];
|
||||
int fwsize;
|
||||
@ -936,10 +942,14 @@ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev)
|
||||
dev_dbg(&dev->dev, "device initialised!\n");
|
||||
|
||||
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
|
||||
&dev->descriptor, sizeof(dev->descriptor));
|
||||
config = dev->actconfig;
|
||||
&new_device_descriptor, sizeof(new_device_descriptor));
|
||||
if (err < 0)
|
||||
dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
|
||||
if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations)
|
||||
dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n",
|
||||
new_device_descriptor.bNumConfigurations);
|
||||
else
|
||||
memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor));
|
||||
|
||||
err = usb_reset_configuration(dev);
|
||||
if (err < 0)
|
||||
@ -1249,6 +1259,7 @@ static void mbox3_setup_defaults(struct usb_device *dev)
|
||||
static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
|
||||
{
|
||||
struct usb_host_config *config = dev->actconfig;
|
||||
struct usb_device_descriptor new_device_descriptor;
|
||||
int err;
|
||||
int descriptor_size;
|
||||
|
||||
@ -1262,10 +1273,14 @@ static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
|
||||
dev_dbg(&dev->dev, "MBOX3: device initialised!\n");
|
||||
|
||||
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
|
||||
&dev->descriptor, sizeof(dev->descriptor));
|
||||
config = dev->actconfig;
|
||||
&new_device_descriptor, sizeof(new_device_descriptor));
|
||||
if (err < 0)
|
||||
dev_dbg(&dev->dev, "MBOX3: error usb_get_descriptor: %d\n", err);
|
||||
if (new_device_descriptor.bNumConfigurations > dev->descriptor.bNumConfigurations)
|
||||
dev_dbg(&dev->dev, "MBOX3: error too large bNumConfigurations: %d\n",
|
||||
new_device_descriptor.bNumConfigurations);
|
||||
else
|
||||
memcpy(&dev->descriptor, &new_device_descriptor, sizeof(dev->descriptor));
|
||||
|
||||
err = usb_reset_configuration(dev);
|
||||
if (err < 0)
|
||||
|
2
tools/testing/selftests/alsa/.gitignore
vendored
2
tools/testing/selftests/alsa/.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
global-timer
|
||||
mixer-test
|
||||
pcm-test
|
||||
test-pcmtest-driver
|
||||
utimer-test
|
||||
|
Loading…
Reference in New Issue
Block a user