projects/linux·commit 4982d355

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

4982d355 · Linus Torvalds <[email protected]> · 2026-09-17 09:57:09 -07:00

Pull sound fixes from Takashi Iwai:
 "A collection of small fixes. Most of them are device-specific fixes
  while there are a few core fixes. The continued flux, but not too
  scaring yet. Some highlights below.

  ALSA Core:
   - Fix potential UAF after asynchronous card release
   - Fix a race condition in PCM timer initialization order

  USB-Audio:
   - Hardening fixes for issues reported by fuzzer for 6fire, bcd2000,
     and implicit FB packets
   - Fix double list addition in implicit FB handling
   - Quirks for AVerMedia GC553Pro and Behringer FCA1616

  HD-Audio:
   - Quirks / fixes for HP OmniBook 7, OMEN 15, and Victus 15 laptops

  ASoC:
   - Support for DAI link codec channel mask to avoid mismatches
   - Fix HDMI-codec channel status change report
   - Fixes for various codecs and platforms: Realtek rt712/rt721
     (calibration, reset fixes), Cirrus Logic (empty EFI variable
     validation, capture channel fixup), AMD ACP SoundWire (bounds
     checks, refactorings), ADAU1977 (OF match table support, SPI
     cleanups), ES8336 (Huawei Matebook B3-420 quirk), UX500 (macro
     fix)"

* tag 'sound-7.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (33 commits)
  ASoC: adau1977-i2c: add OF match table for I2C
  ASoC: adau1977-spi: drop __maybe_unused and of_match_ptr()
  ASoC: adau1977: make the Kconfig symbols user selectable
  ASoC: amd: acp: fix card name length warning in SOF SoundWire machine driver
  ASoC: amd: acp: fix ffs() operator precedence for SoundWire link ID
  ASoC: amd: acp: refactor codec config count in SOF SoundWire machine driver
  ASoC: amd: acp: bounds-check SoundWire link ID in machine drivers
  ASoC: cs-amp-lib: Prevent NULL pointer if efi variable is zero length
  ASoC: codecs: rt712-sdca-dmic: fix uninitialized stream_config->type
  ASoC: hdmi-codec: Report a change when the channel status moves
  ASoC: ux500: Parenthesize MSP_{RX,TX}_CLKPOL_BIT() arguments
  ASoC: rt721: Reset codec to fix abnormal sound
  ALSA: usb-audio: fix list_add double-add in push_back_to_ready_list
  ALSA: hda: trace PCM open only after assigning a stream
  ALSA: usb-audio: skip the broken mute control on AVerMedia GC553Pro
  ALSA: hda/realtek: Enable mute LEDs on HP OmniBook 7 17-dc0xxx
  ALSA: 6fire: fix OOB write from device-reported iso length
  ALSA: usb-audio: Add capture quirk for Behringer FCA1616
  ALSA: hda/realtek: Add mute LED quirk for HP OMEN 15-ax
  ASoC: Intel: sof_es8336: Add a quirk for Huawei Matebook B3-420
  ...
Commit
4982d3552a3bf94de503acf93433277d08421de6
Parents
f143ea21 · 546b928d

Merge commit. Changes below are compared with the first parent: f143ea21.

Changes

32 files changed · +316 −119

FileStatusAddDelContent
include/sound/soc.hmodified+2−1View file
include/sound/soc_sdw_utils.hmodified+0−2View file
sound/core/init.cmodified+2−1View file
sound/core/pcm_timer.cmodified+5−2View file
sound/hda/codecs/realtek/alc269.cmodified+10−1View file
sound/hda/common/controller.cmodified+1−1View file
sound/soc/amd/acp/acp-sdw-legacy-mach.cmodified+12−2View file
sound/soc/amd/acp/acp-sdw-sof-mach.cmodified+17−6View file
sound/soc/codecs/Kconfigmodified+2−2View file
sound/soc/codecs/adau1977-i2c.cmodified+9−0View file
sound/soc/codecs/adau1977-spi.cmodified+6−6View file
sound/soc/codecs/cs-amp-lib.cmodified+2−0View file
sound/soc/codecs/hdmi-codec.cmodified+5−1View file
sound/soc/codecs/rt712-sdca-dmic.cmodified+5−9View file
sound/soc/codecs/rt712-sdca-sdw.cmodified+8−0View file
sound/soc/codecs/rt712-sdca.cmodified+83−3View file
sound/soc/codecs/rt712-sdca.hmodified+18−0View file
sound/soc/codecs/rt721-sdca-sdw.cmodified+3−0View file
sound/soc/codecs/rt721-sdca.cmodified+17−0View file
sound/soc/codecs/wm_adsp.cmodified+4−1View file
sound/soc/intel/boards/sof_es8336.cmodified+9−0View file
sound/soc/sdw_utils/soc_sdw_cs_amp.cmodified+0−46View file
sound/soc/sdw_utils/soc_sdw_utils.cmodified+14−10View file
sound/soc/soc-pcm.cmodified+13−5View file
sound/soc/ux500/ux500_msp_i2s.hmodified+2−2View file
sound/usb/6fire/pcm.cmodified+10−2View file
sound/usb/bcd2000/bcd2000.cmodified+26−7View file
sound/usb/card.hmodified+1−0View file
sound/usb/endpoint.cmodified+14−7View file
sound/usb/implicit.cmodified+1−0View file
sound/usb/mixer_maps.cmodified+13−0View file
sound/virtio/virtio_card.cmodified+2−2View file

Only the first 600 diff lines are shown. Download the complete patch.

include/sound/soc.h

View file
diff --git a/include/sound/soc.h b/include/sound/soc.h
index f46b2bc..5afc34b 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -699,7 +699,8 @@ struct snd_soc_dai_link_component {
struct snd_soc_dai_link_ch_map {
unsigned int cpu;
unsigned int codec;
- unsigned int ch_mask;
+ unsigned int cpu_ch_mask;
+ unsigned int codec_ch_mask;
};
struct snd_soc_dai_link {

include/sound/soc_sdw_utils.h

View file
diff --git a/include/sound/soc_sdw_utils.h b/include/sound/soc_sdw_utils.h
index 9b28e9a..9fbb69b 100644
--- a/include/sound/soc_sdw_utils.h
+++ b/include/sound/soc_sdw_utils.h
@@ -250,8 +250,6 @@ int asoc_sdw_cs_amp_init(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_links,
struct asoc_sdw_codec_info *info,
bool playback);
-int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd,
- struct snd_soc_dai *dai);
int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix);
/* MAXIM codec support */

sound/core/init.c

View file
diff --git a/sound/core/init.c b/sound/core/init.c
index 9693e64..1bcb6a2 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -310,7 +310,7 @@ static int snd_card_init(struct snd_card *card, struct device *parent,
kfree(card); /* manually free here, as no destructor called */
return err;
}
- card->dev = parent;
+ card->dev = get_device(parent);
card->number = idx;
WARN_ON(IS_MODULE(CONFIG_SND) && !module);
card->module = module;
@@ -603,6 +603,7 @@ static int snd_card_do_free(struct snd_card *card)
dev_warn(card->dev, "unable to free card info\n");
/* Not fatal error */
}
+ put_device(card->dev);
if (card->release_completion)
complete(card->release_completion);
if (!managed)

sound/core/pcm_timer.c

View file
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index ab0e5bd..18bedd6 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -111,12 +111,15 @@ void snd_pcm_timer_init(struct snd_pcm_substream *substream)
snd_pcm_direction_name(substream->stream),
tid.card, tid.device, tid.subdevice);
timer->hw = snd_pcm_timer;
+ /* Set before registering: a concurrent reader can invoke our hw
+ * callbacks as soon as the timer is on the global list.
+ */
+ timer->private_data = substream;
+ timer->private_free = snd_pcm_timer_free;
if (snd_device_register(timer->card, timer) < 0) {
snd_device_free(timer->card, timer);
return;
}
- timer->private_data = substream;
- timer->private_free = snd_pcm_timer_free;
substream->timer = timer;
}

sound/hda/codecs/realtek/alc269.c

View file
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index 3abee61..5127a11 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -4303,6 +4303,7 @@ enum {
ALC287_FIXUP_LEGION_16ACHG6,
ALC287_FIXUP_CS35L41_I2C_2,
ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED,
+ ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS,
ALC287_FIXUP_CS35L41_I2C_4,
ALC245_FIXUP_CS35L41_SPI_1,
ALC245_FIXUP_CS35L41_SPI_2,
@@ -6614,6 +6615,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC285_FIXUP_HP_MUTE_LED,
},
+ [ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cs35l41_fixup_i2c_two,
+ .chained = true,
+ .chain_id = ALC245_FIXUP_HP_X360_MUTE_LEDS,
+ },
[ALC287_FIXUP_CS35L41_I2C_4] = {
.type = HDA_FIXUP_FUNC,
.v.func = cs35l41_fixup_i2c_four,
@@ -7358,6 +7365,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8158, "HP", ALC256_FIXUP_HP_HEADSET_MIC),
SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC295_FIXUP_HP_X360),
SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
+ SND_PCI_QUIRK(0x103c, 0x8259, "HP OMEN 15-ax202nf", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
SND_PCI_QUIRK(0x103c, 0x827f, "HP x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
@@ -7568,6 +7576,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8b96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x8b97, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF),
SND_PCI_QUIRK(0x103c, 0x8ba9, "HP Omen 16-wd0xxx", ALC245_FIXUP_HP_MUTE_LED_V1_COEFBIT),
+ SND_PCI_QUIRK(0x103c, 0x8bb1, "HP Victus 15-fa1xxx (MB 8BB1)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
SND_PCI_QUIRK(0x103c, 0x8bb3, "HP Slim OMEN", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8bb4, "HP Slim OMEN", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8bb6, "HP Laptop 15-fd0039nt", ALC236_FIXUP_HP_15_FD0XXX),
@@ -7660,7 +7669,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8d92, "HP ZBook Firefly 16 G12", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8dcd, "HP Victus 15-fa2xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
SND_PCI_QUIRK(0x103c, 0x8d9b, "HP 17 Turbine OmniBook 7 UMA", ALC287_FIXUP_CS35L41_I2C_2),
- SND_PCI_QUIRK(0x103c, 0x8d9c, "HP 17 Turbine OmniBook 7 DIS", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x103c, 0x8d9c, "HP 17 Turbine OmniBook 7 DIS", ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS),
SND_PCI_QUIRK(0x103c, 0x8d9d, "HP 17 Turbine OmniBook X UMA", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8d9e, "HP 17 Turbine OmniBook X DIS", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8d9f, "HP 14 Cadet (x360)", ALC287_FIXUP_CS35L41_I2C_2),

sound/hda/common/controller.c

View file
diff --git a/sound/hda/common/controller.c b/sound/hda/common/controller.c
index afec5c5..18dae02 100644
--- a/sound/hda/common/controller.c
+++ b/sound/hda/common/controller.c
@@ -586,11 +586,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
snd_hda_codec_pcm_get(apcm->info);
mutex_lock(&chip->open_mutex);
azx_dev = azx_assign_device(chip, substream);
- trace_azx_pcm_open(chip, azx_dev);
if (azx_dev == NULL) {
err = -EBUSY;
goto unlock;
}
+ trace_azx_pcm_open(chip, azx_dev);
runtime->private_data = azx_dev;
runtime->hw = azx_pcm_hw;

sound/soc/amd/acp/acp-sdw-legacy-mach.c

View file
diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c
index 6eac42b..1a05d42 100644
--- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c
+++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c
@@ -205,9 +205,19 @@ static int create_sdw_dailink(struct snd_soc_card *card,
return -EINVAL;
}
+ if (!soc_end->link_mask) {
+ dev_err(dev, "invalid zero link_mask\n");
+ return -EINVAL;
+ }
+ if ((ffs(soc_end->link_mask) - 1) >= amd_ctx->max_sdw_links) {
+ dev_err(dev, "link_id %d exceeds max_sdw_links %d\n",
+ ffs(soc_end->link_mask) - 1, amd_ctx->max_sdw_links);
+ return -EINVAL;
+ }
+
switch (amd_ctx->acp_rev) {
case ACP63_PCI_REV:
- ret = get_acp63_cpu_pin_id(ffs(soc_end->link_mask - 1),
+ ret = get_acp63_cpu_pin_id(ffs(soc_end->link_mask) - 1,
*be_id, &cpu_pin_id, dev);
if (ret)
return ret;
@@ -215,7 +225,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
case ACP70_PCI_REV:
case ACP71_PCI_REV:
case ACP72_PCI_REV:
- ret = get_acp70_cpu_pin_id(ffs(soc_end->link_mask - 1),
+ ret = get_acp70_cpu_pin_id(ffs(soc_end->link_mask) - 1,
*be_id, &cpu_pin_id, dev);
if (ret)
return ret;

sound/soc/amd/acp/acp-sdw-sof-mach.c

View file
diff --git a/sound/soc/amd/acp/acp-sdw-sof-mach.c b/sound/soc/amd/acp/acp-sdw-sof-mach.c
index a9cd1f3..ec3e1f5 100644
--- a/sound/soc/amd/acp/acp-sdw-sof-mach.c
+++ b/sound/soc/amd/acp/acp-sdw-sof-mach.c
@@ -121,9 +121,18 @@ static int create_sdw_dailink(struct snd_soc_card *card,
return -EINVAL;
}
+ if (!sof_end->link_mask) {
+ dev_err(dev, "invalid zero link_mask\n");
+ return -EINVAL;
+ }
+ if ((ffs(sof_end->link_mask) - 1) >= amd_ctx->max_sdw_links) {
+ dev_err(dev, "link_id %d exceeds max_sdw_links %d\n",
+ ffs(sof_end->link_mask) - 1, amd_ctx->max_sdw_links);
+ return -EINVAL;
+ }
switch (amd_ctx->acp_rev) {
case ACP63_PCI_REV:
- ret = get_acp63_cpu_pin_id(ffs(sof_end->link_mask - 1),
+ ret = get_acp63_cpu_pin_id(ffs(sof_end->link_mask) - 1,
*be_id, &cpu_pin_id, dev);
if (ret)
return ret;
@@ -131,7 +140,7 @@ static int create_sdw_dailink(struct snd_soc_card *card,
case ACP70_PCI_REV:
case ACP71_PCI_REV:
case ACP72_PCI_REV:
- ret = get_acp70_cpu_pin_id(ffs(sof_end->link_mask - 1),
+ ret = get_acp70_cpu_pin_id(ffs(sof_end->link_mask) - 1,
*be_id, &cpu_pin_id, dev);
if (ret)
return ret;
@@ -277,6 +286,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
int num_devs = 0;
int num_ends = 0;
int num_aux = 0;
+ int num_confs;
int num_links;
int be_id = 0;
int ret;
@@ -287,6 +297,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
return ret;
}
+ num_confs = num_ends;
/* One per DAI link, worst case is a DAI link for every endpoint */
struct asoc_sdw_dailink *sof_dais __free(kfree) =
kzalloc_objs(*sof_dais, num_ends);
@@ -303,7 +314,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
if (!sof_aux)
return -ENOMEM;
- ret = asoc_sdw_parse_sdw_endpoints(dev, ctx, sof_aux, sof_dais, sof_ends, &num_devs);
+ ret = asoc_sdw_parse_sdw_endpoints(dev, ctx, sof_aux, sof_dais, sof_ends, &num_confs);
if (ret < 0)
return ret;
@@ -315,7 +326,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
dev_dbg(dev, "sdw %d, dmic %d", sdw_be_num, dmic_num);
- codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
+ codec_conf = devm_kcalloc(dev, num_confs, sizeof(*codec_conf), GFP_KERNEL);
if (!codec_conf)
return -ENOMEM;
@@ -326,7 +337,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
return -ENOMEM;
card->codec_conf = codec_conf;
- card->num_configs = num_devs;
+ card->num_configs = num_confs;
card->dai_link = dai_links;
card->num_links = num_links;
card->aux_dev = sof_aux;
@@ -379,7 +390,7 @@ static int mc_probe(struct platform_device *pdev)
ctx->private = amd_ctx;
card = &ctx->card;
card->dev = &pdev->dev;
- card->name = "amd-soundwire";
+ card->name = "amd-sdw";
card->owner = THIS_MODULE;
card->late_probe = asoc_sdw_card_late_probe;

sound/soc/codecs/Kconfig

View file
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index f9a47e2..d88593c 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -524,13 +524,13 @@ config SND_SOC_ADAU1977
tristate
config SND_SOC_ADAU1977_SPI
- tristate
+ tristate "Analog Devices ADAU1977/ADAU1978/ADAU1979 CODEC - SPI"
depends on SPI_MASTER
select SND_SOC_ADAU1977
select REGMAP_SPI
config SND_SOC_ADAU1977_I2C
- tristate
+ tristate "Analog Devices ADAU1977/ADAU1978/ADAU1979 CODEC - I2C"
depends on I2C
select SND_SOC_ADAU1977
select REGMAP_I2C

sound/soc/codecs/adau1977-i2c.c

View file
diff --git a/sound/soc/codecs/adau1977-i2c.c b/sound/soc/codecs/adau1977-i2c.c
index d1c6c4d..5a11caf 100644
--- a/sound/soc/codecs/adau1977-i2c.c
+++ b/sound/soc/codecs/adau1977-i2c.c
@@ -34,9 +34,18 @@ static const struct i2c_device_id adau1977_i2c_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, adau1977_i2c_ids);
+static const struct of_device_id adau1977_i2c_of_match[] = {
+ { .compatible = "adi,adau1977" },
+ { .compatible = "adi,adau1978" },
+ { .compatible = "adi,adau1979" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, adau1977_i2c_of_match);
+
static struct i2c_driver adau1977_i2c_driver = {
.driver = {
.name = "adau1977",
+ .of_match_table = adau1977_i2c_of_match,
},
.probe = adau1977_i2c_probe,
.id_table = adau1977_i2c_ids,

sound/soc/codecs/adau1977-spi.c

View file
diff --git a/sound/soc/codecs/adau1977-spi.c b/sound/soc/codecs/adau1977-spi.c
index 878cde9..c98da5b 100644
--- a/sound/soc/codecs/adau1977-spi.c
+++ b/sound/soc/codecs/adau1977-spi.c
@@ -53,18 +53,18 @@ static const struct spi_device_id adau1977_spi_ids[] = {
};
MODULE_DEVICE_TABLE(spi, adau1977_spi_ids);
-static const struct of_device_id adau1977_spi_of_match[] __maybe_unused = {
- { .compatible = "adi,adau1977" },
- { .compatible = "adi,adau1978" },
- { .compatible = "adi,adau1979" },
- { },
+static const struct of_device_id adau1977_spi_of_match[] = {
+ { .compatible = "adi,adau1977" },
+ { .compatible = "adi,adau1978" },
+ { .compatible = "adi,adau1979" },
+ { },
};
MODULE_DEVICE_TABLE(of, adau1977_spi_of_match);
static struct spi_driver adau1977_spi_driver = {
.driver = {
.name = "adau1977",
- .of_match_table = of_match_ptr(adau1977_spi_of_match),
+ .of_match_table = adau1977_spi_of_match,
},
.probe = adau1977_spi_probe,
.id_table = adau1977_spi_ids,

sound/soc/codecs/cs-amp-lib.c

View file
diff --git a/sound/soc/codecs/cs-amp-lib.c b/sound/soc/codecs/cs-amp-lib.c
index 41a9a5b..9bc19d2 100644
--- a/sound/soc/codecs/cs-amp-lib.c
+++ b/sound/soc/codecs/cs-amp-lib.c
@@ -317,6 +317,8 @@ static void *cs_amp_alloc_get_efi_variable(efi_char16_t *name,
unsigned long size = 0;
status = cs_amp_get_efi_variable(name, guid, NULL, &size, NULL);
+ if (status == EFI_SUCCESS)
+ return ERR_PTR(-ENOENT);
if (status != EFI_BUFFER_TOO_SMALL)
return ERR_PTR(cs_amp_convert_efi_status(status));

sound/soc/codecs/hdmi-codec.c

View file
diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index bc2c224..7aa50c5 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -426,10 +426,14 @@ static int hdmi_codec_iec958_default_put(struct snd_kcontrol *kcontrol,
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
+ if (!memcmp(hcp->iec_status, ucontrol->value.iec958.status,
+ sizeof(hcp->iec_status)))
+ return 0;
+
memcpy(hcp->iec_status, ucontrol->value.iec958.status,
sizeof(hcp->iec_status));
- return 0;
+ return 1;
}
static int hdmi_codec_iec958_mask_get(struct snd_kcontrol *kcontrol,

sound/soc/codecs/rt712-sdca-dmic.c

View file
diff --git a/sound/soc/codecs/rt712-sdca-dmic.c b/sound/soc/codecs/rt712-sdca-dmic.c
index 8860d81..a9f3aa4 100644
--- a/sound/soc/codecs/rt712-sdca-dmic.c
+++ b/sound/soc/codecs/rt712-sdca-dmic.c
@@ -13,6 +13,7 @@
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/sdw.h>
#include <sound/tlv.h>
#include "rt712-sdca.h"
#include "rt712-sdca-dmic.h"
@@ -632,10 +633,10 @@ static int rt712_sdca_dmic_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
- struct sdw_stream_config stream_config;
+ struct sdw_stream_config stream_config = {0};
struct sdw_port_config port_config;
struct sdw_stream_runtime *sdw_stream;
- int retval, num_channels;
+ int retval;
unsigned int sampling_rate;
dev_dbg(dai->dev, "%s %s", __func__, dai->name);
@@ -647,13 +648,8 @@ static int rt712_sdca_dmic_hw_params(struct snd_pcm_substream *substream,
if (!rt712->slave)
return -EINVAL;
- stream_config.frame_rate = params_rate(params);
- stream_config.ch_count = params_channels(params);
- stream_config.bps = snd_pcm_format_width(params_format(params));
- stream_config.direction = SDW_DATA_DIR_TX;
-
- num_channels = params_channels(params);
- port_config.ch_mask = GENMASK(num_channels - 1, 0);
+ /* SoundWire specific configuration */
+ snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
port_config.num = 2;
retval = sdw_stream_add_slave(rt712->slave, &stream_config,

sound/soc/codecs/rt712-sdca-sdw.c

View file
diff --git a/sound/soc/codecs/rt712-sdca-sdw.c b/sound/soc/codecs/rt712-sdca-sdw.c
index c50e74e..edba036 100644
--- a/sound/soc/codecs/rt712-sdca-sdw.c
+++ b/sound/soc/codecs/rt712-sdca-sdw.c
@@ -18,12 +18,16 @@
static bool rt712_sdca_readable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
+ case 0x004d:
case 0x201a ... 0x201f:
case 0x2029 ... 0x202a:
case 0x202d ... 0x2034:
case 0x2230 ... 0x2232:
case 0x2f01 ... 0x2f0a:
case 0x2f35 ... 0x2f36:
+ case 0x2f3a:
+ case 0x2f3d:
+ case 0x2f41:
case 0x2f50:
case 0x2f54:
case 0x2f58 ... 0x2f5d:
@@ -48,6 +52,7 @@ static bool rt712_sdca_readable_register(struct device *dev, unsigned int reg)
static bool rt712_sdca_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
+ case 0x004d:
case 0x201b:
case 0x201c:
case 0x201d:
@@ -56,6 +61,9 @@ static bool rt712_sdca_volatile_register(struct device *dev, unsigned int reg)
case 0x2230:
case 0x2f01:
case 0x2f35:
+ case 0x2f3a:
+ case 0x2f3d:
+ case 0x2f41:
case 0x320c:
case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0):
case SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ...

sound/soc/codecs/rt712-sdca.c

View file
diff --git a/sound/soc/codecs/rt712-sdca.c b/sound/soc/codecs/rt712-sdca.c
index eda87eb..38052cb 100644
--- a/sound/soc/codecs/rt712-sdca.c
+++ b/sound/soc/codecs/rt712-sdca.c
@@ -73,14 +73,57 @@ static int rt712_sdca_index_update_bits(struct rt712_sdca_priv *rt712,
return rt712_sdca_index_write(rt712, nid, reg, tmp);
}
+static void rt712_sdca_clk_patch(struct rt712_sdca_priv *rt712)
+{
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0000);
+ regmap_write(rt712->regmap, RT712_SDW_ROOT_CLK, 0x03);
+ usleep_range(1000, 1100);
+ regmap_write(rt712->regmap, RT712_SDW_ROOT_CLK, 0x02);
+ usleep_range(1000, 1100);
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF2, 0x0080, 0x0000);
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF2, 0x001f, 0x0017);
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF3, 0x0010, 0x0000);
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF1, 0x0081, 0x0001);
+ regmap_write(rt712->regmap, RT712_SDW_ROOT_CLK, 0x03);
+ usleep_range(1000, 1100);
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF1, 0x0081, 0x0081);
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF2, 0x0080, 0x0080);
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF2, 0x001f, 0x0000);
+ regmap_update_bits(rt712->regmap, RT712_PLL2_CONF3, 0x0010, 0x0010);
+ usleep_range(1000, 1100);
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0081);
+}
+
+static void rt712_sdca_clk_patch2(struct rt712_sdca_priv *rt712)
+{
+ rt712_sdca_index_update_bits(rt712, RT712_VENDOR_REG, 0x49, 0x0800,
+ 0x0000);
+ rt712_sdca_index_update_bits(rt712, RT712_VENDOR_REG, 0x49, 0xf000,
+ 0x0000);
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0000);
+ rt712_sdca_index_update_bits(rt712, RT712_VENDOR_ANALOG_CTL, 0x0c, 0xc000,
+ 0xc000);
+ rt712_sdca_index_update_bits(rt712, RT712_VENDOR_ANALOG_CTL, 0x00, 0xc000,
+ 0xc000);
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0081);
+ regmap_write(rt712->regmap, RT712_SDW_ROOT_CLK, 0x02);
+ usleep_range(1000, 1100);
+ regmap_write(rt712->regmap, RT712_SDW_ROOT_CLK, 0x03);
+ usleep_range(1000, 1100);
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, 0x65, 0x0000);
+}
+
static int rt712_sdca_calibration(struct rt712_sdca_priv *rt712)
{
unsigned int val, loop_rc = 0, loop_dc = 0;
struct device *dev;
struct regmap *regmap = rt712->regmap;
+ unsigned int clk_base;
int chk_cnt = 100;
int ret = 0;
+ regmap_read(rt712->regmap, RT712_SDW_ROOT_CLK, &clk_base);
+
mutex_lock(&rt712->calibrate_mutex);
dev = regmap_get_device(regmap);
@@ -109,8 +152,35 @@ static int rt712_sdca_calibration(struct rt712_sdca_priv *rt712)
if (ret < 0)
goto _cali_fail_;
}
- if (loop_dc == chk_cnt)
- dev_err(dev, "%s, calibration time-out!\n", __func__);
+
+ if (loop_dc == chk_cnt) {
+ if (clk_base == RT712_CLK_FREQ_24_576MHZ) {
+ rt712_sdca_clk_patch(rt712);
+ rt712_sdca_clk_patch2(rt712);
+ }
+ rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_FSM_CTL, 0x4100);
+ rt712_sdca_index_write(rt712, RT712_VENDOR_CALI,
+ RT712_DAC_DC_CALI_CTL1, 0x7883);
+ rt712_sdca_index_write(rt712, RT712_VENDOR_CALI,
+ RT712_DAC_DC_CALI_CTL1, 0xf893);
+ rt712_sdca_index_read(rt712, RT712_VENDOR_CALI,
+ RT712_DAC_DC_CALI_CTL1, &val);
+
+ for (loop_dc = 0; loop_dc < chk_cnt &&
+ (val & RT712_DAC_DC_CALI_TRIGGER); loop_dc++) {
+ usleep_range(10000, 11000);
+ ret = rt712_sdca_index_read(rt712, RT712_VENDOR_CALI,
+ RT712_DAC_DC_CALI_CTL1, &val);
+
+ if (ret < 0)
+ goto _cali_fail_;
+ }
+
+ if (loop_dc == chk_cnt)
+ dev_err(dev, "%s, calibration time-out!\n", __func__);
+ else
+ dev_dbg(dev, "%s, calibration success!\n", __func__);
+ }
if (loop_dc == chk_cnt || loop_rc == chk_cnt)
ret = -ETIMEDOUT;
@@ -1759,9 +1829,13 @@ static void rt712_sdca_va_io_init(struct rt712_sdca_priv *rt712)
static void rt712_sdca_vb_io_init(struct rt712_sdca_priv *rt712)
{
- int ret = 0;
unsigned int jack_func_status, mic_func_status, amp_func_status;
struct device *dev = &rt712->slave->dev;
+ unsigned int clk_base;
+ int ret = 0;
+
+ regmap_read(rt712->regmap, RT712_SDW_ROOT_CLK, &clk_base);
+ dev_dbg(dev, "%s clk_base=%x", __func__, clk_base);
regmap_read(rt712->regmap,
SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0), &jack_func_status);
@@ -1773,6 +1847,12 @@ static void rt712_sdca_vb_io_init(struct rt712_sdca_priv *rt712)
__func__, jack_func_status, mic_func_status, amp_func_status);
rt712_sdca_index_write(rt712, RT712_VENDOR_REG, RT712_JD_CTL3, 0x7778);
+
+ if (clk_base == RT712_CLK_FREQ_24_576MHZ) {
+ rt712_sdca_clk_patch(rt712);
+ rt712_sdca_clk_patch2(rt712);
+ }
+
/* DMIC */
if ((mic_func_status & FUNCTION_NEEDS_INITIALIZATION) || (!rt712->first_hw_init)) {
rt712_sdca_index_write(rt712, RT712_VENDOR_HDA_CTL, RT712_DMIC2_FU_IT_FLOAT_CTL, 0x1526);

sound/soc/codecs/rt712-sdca.h

View file
diff --git a/sound/soc/codecs/rt712-sdca.h b/sound/soc/codecs/rt712-sdca.h
index 4674028..6229fe3 100644
--- a/sound/soc/codecs/rt712-sdca.h
+++ b/sound/soc/codecs/rt712-sdca.h
@@ -162,6 +162,16 @@ struct rt712_dmic_kctrl_priv {
#define RT712_EAPD_HIGH 0x2
#define RT712_EAPD_LOW 0x0
+/* SDW clock root frequency */
+#define RT712_SDW_ROOT_CLK 0x004d
+#define RT712_SDW_SCALE_CLK0 0x0062
+#define RT712_SDW_SCALE_CLK1 0x0072
+
+/* PLL2 config */
+#define RT712_PLL2_CONF1 0x2f3a
+#define RT712_PLL2_CONF2 0x2f3d
+#define RT712_PLL2_CONF3 0x2f41
+
/* RC Calibration register */
#define RT712_RC_CAL 0x3201
@@ -254,6 +264,14 @@ enum rt712_sdca_version {
RT712_VB,
};
+enum {
+ RT712_CLK_FREQ_19_2_MHZ = 1,
+ RT712_CLK_FREQ_24MHZ = 2,
+ RT712_CLK_FREQ_24_576MHZ = 3,
+ RT712_CLK_FREQ_22_5792MHZ = 4,
+};

This diff is incomplete. Download the complete patch.

sound/soc/codecs/rt721-sdca-sdw.c

View file

This diff is incomplete. Download the complete patch.

sound/soc/codecs/rt721-sdca.c

View file

This diff is incomplete. Download the complete patch.

sound/soc/codecs/wm_adsp.c

View file

This diff is incomplete. Download the complete patch.

sound/soc/intel/boards/sof_es8336.c

View file

This diff is incomplete. Download the complete patch.

sound/soc/sdw_utils/soc_sdw_cs_amp.c

View file

This diff is incomplete. Download the complete patch.

sound/soc/sdw_utils/soc_sdw_utils.c

View file

This diff is incomplete. Download the complete patch.

sound/soc/soc-pcm.c

View file

This diff is incomplete. Download the complete patch.

sound/soc/ux500/ux500_msp_i2s.h

View file

This diff is incomplete. Download the complete patch.

sound/usb/6fire/pcm.c

View file

This diff is incomplete. Download the complete patch.

sound/usb/bcd2000/bcd2000.c

View file

This diff is incomplete. Download the complete patch.

sound/usb/card.h

View file

This diff is incomplete. Download the complete patch.

sound/usb/endpoint.c

View file

This diff is incomplete. Download the complete patch.

sound/usb/implicit.c

View file

This diff is incomplete. Download the complete patch.

sound/usb/mixer_maps.c

View file

This diff is incomplete. Download the complete patch.

sound/virtio/virtio_card.c

View file

This diff is incomplete. Download the complete patch.