summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/core/misc.c8
-rw-r--r--sound/core/seq/seq_clientmgr.c2
-rw-r--r--sound/core/seq/seq_clientmgr.h5
-rw-r--r--sound/core/seq/seq_ump_client.c2
-rw-r--r--sound/drivers/pcmtest.c6
-rw-r--r--sound/firewire/tascam/tascam-hwdep.c1
-rw-r--r--sound/hda/codecs/realtek/alc269.c53
-rw-r--r--sound/soc/amd/yc/acp6x-mach.c21
-rw-r--r--sound/soc/codecs/ab8500-codec.c304
-rw-r--r--sound/soc/codecs/cs35l56-shared.c11
-rw-r--r--sound/soc/codecs/cs35l56.c11
-rw-r--r--sound/soc/codecs/tas2764.c35
-rw-r--r--sound/soc/codecs/tas2770.c23
-rw-r--r--sound/soc/codecs/wm_adsp_fw_find_test.c57
-rw-r--r--sound/soc/fsl/fsl_xcvr.c17
-rw-r--r--sound/soc/sdw_utils/soc_sdw_utils.c1
-rw-r--r--sound/soc/spacemit/k1_i2s.c7
-rw-r--r--sound/sparc/dbri.c1
-rw-r--r--sound/usb/clock.c15
-rw-r--r--sound/usb/midi2.c9
-rw-r--r--sound/usb/quirks.c7
21 files changed, 243 insertions, 353 deletions
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 5aca09edf971..833124c8e4fa 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -148,9 +148,11 @@ EXPORT_SYMBOL_GPL(snd_fasync_helper);
void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll)
{
- if (!fasync || !fasync->on)
+ if (!fasync)
return;
guard(spinlock_irqsave)(&snd_fasync_lock);
+ if (!fasync->on)
+ return;
fasync->signal = signal;
fasync->poll = poll;
list_move(&fasync->list, &snd_fasync_list);
@@ -163,8 +165,10 @@ void snd_fasync_free(struct snd_fasync *fasync)
if (!fasync)
return;
- scoped_guard(spinlock_irq, &snd_fasync_lock)
+ scoped_guard(spinlock_irq, &snd_fasync_lock) {
+ fasync->on = 0;
list_del_init(&fasync->list);
+ }
flush_work(&snd_fasync_work);
kfree(fasync);
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index 75a7a2af9d8c..5719637575a9 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1253,7 +1253,7 @@ static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client,
if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 3))
client->midi_version = client_info->midi_version;
memcpy(client->event_filter, client_info->event_filter, 32);
- client->group_filter = client_info->group_filter;
+ client->group_filter = client_info->group_filter & SND_SEQ_GROUP_FILTER_MASK;
/* notify the change */
snd_seq_system_client_ev_client_change(client->number);
diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h
index ece02c58db70..feea8bb7d987 100644
--- a/sound/core/seq/seq_clientmgr.h
+++ b/sound/core/seq/seq_clientmgr.h
@@ -14,6 +14,9 @@
/* client manager */
+#define SND_SEQ_GROUP_FILTER_MASK GENMASK(SNDRV_UMP_MAX_GROUPS, 0)
+#define SND_SEQ_GROUP_FILTER_GROUPS GENMASK(SNDRV_UMP_MAX_GROUPS, 1)
+
struct snd_seq_user_client {
struct file *file; /* file struct of client */
/* ... */
@@ -40,7 +43,7 @@ struct snd_seq_client {
int number; /* client number */
unsigned int filter; /* filter flags */
DECLARE_BITMAP(event_filter, 256);
- unsigned short group_filter;
+ unsigned int group_filter;
snd_use_lock_t use_lock;
int event_lost;
/* ports */
diff --git a/sound/core/seq/seq_ump_client.c b/sound/core/seq/seq_ump_client.c
index fdc76f23e03f..9079ccfdc866 100644
--- a/sound/core/seq/seq_ump_client.c
+++ b/sound/core/seq/seq_ump_client.c
@@ -369,7 +369,7 @@ static void setup_client_group_filter(struct seq_ump_client *client)
cptr = snd_seq_kernel_client_get(client->seq_client);
if (!cptr)
return;
- filter = ~(1U << 0); /* always allow groupless messages */
+ filter = SND_SEQ_GROUP_FILTER_GROUPS; /* always allow groupless messages */
for (p = 0; p < SNDRV_UMP_MAX_GROUPS; p++) {
if (client->ump->groups[p].active)
filter &= ~(1U << (p + 1));
diff --git a/sound/drivers/pcmtest.c b/sound/drivers/pcmtest.c
index 5bfec4c7bf71..7f93557b51ec 100644
--- a/sound/drivers/pcmtest.c
+++ b/sound/drivers/pcmtest.c
@@ -679,9 +679,9 @@ static ssize_t pattern_read(struct file *file, char __user *u_buff, size_t len,
return 0;
if (copy_to_user(u_buff, patt_buf->buf + *off, to_read))
- to_read = 0;
- else
- *off += to_read;
+ return -EFAULT;
+
+ *off += to_read;
return to_read;
}
diff --git a/sound/firewire/tascam/tascam-hwdep.c b/sound/firewire/tascam/tascam-hwdep.c
index 867b4ea1096e..6270263e7bf4 100644
--- a/sound/firewire/tascam/tascam-hwdep.c
+++ b/sound/firewire/tascam/tascam-hwdep.c
@@ -73,6 +73,7 @@ static long tscm_hwdep_read_queue(struct snd_tscm *tscm, char __user *buf,
length = rounddown(remained, sizeof(*entries));
if (length == 0)
break;
+ tail_pos = head_pos + length / sizeof(*entries);
spin_unlock_irq(&tscm->lock);
if (copy_to_user(pos, &entries[head_pos], length))
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index a9cd03bb73c4..11d0ea8ed859 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -1669,6 +1669,21 @@ static void alc295_fixup_hp_mute_led_coefbit11(struct hda_codec *codec,
}
}
+/* Override wrong pin to NID 0x1b (F.32 BIOS reports 0x18 via DMI OEM string)
+ * on HP pavilion 15-cs1xxx laptops
+ */
+static void alc295_fixup_hp_pavilion_mute_led_1b(struct hda_codec *codec,
+ const struct hda_fixup *fix,
+ int action)
+{
+ struct alc_spec *spec = codec->spec;
+
+ alc269_fixup_hp_mute_led(codec, fix, action);
+
+ if (action == HDA_FIXUP_ACT_PRE_PROBE)
+ spec->mute_led_nid = 0x1b;
+}
+
static void alc233_fixup_lenovo_coef_micmute_led(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
@@ -3390,6 +3405,19 @@ static void alc256_fixup_mic_no_presence_and_resume(struct hda_codec *codec,
}
}
+static void alc256_fixup_xiaomi_pro15_resume(struct hda_codec *codec,
+ const struct hda_fixup *fix,
+ int action)
+{
+ /*
+ * On the Xiaomi Mi Laptop Pro 15 (TM1905, SSID 1d72:1905) the ALC256
+ * codec sets coefficient 0x10 bit 9 to 1 after S3 resume, silencing
+ * the internal speaker. Bluetooth and HDMI audio are unaffected.
+ * Clear the bit so the speaker keeps working across suspend cycles.
+ */
+ alc_update_coef_idx(codec, 0x10, 1<<9, 0);
+}
+
static void alc256_decrease_headphone_amp_val(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
@@ -3857,6 +3885,7 @@ enum {
ALC290_FIXUP_SUBWOOFER,
ALC290_FIXUP_SUBWOOFER_HSJACK,
ALC295_FIXUP_HP_MUTE_LED_COEFBIT11,
+ ALC295_FIXUP_HP_PAVILION_MUTE_LED_1B,
ALC269_FIXUP_THINKPAD_ACPI,
ALC269_FIXUP_LENOVO_XPAD_ACPI,
ALC269_FIXUP_DMIC_THINKPAD_ACPI,
@@ -4052,6 +4081,7 @@ enum {
ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
ALC233_FIXUP_NO_AUDIO_JACK,
ALC256_FIXUP_MIC_NO_PRESENCE_AND_RESUME,
+ ALC256_FIXUP_XIAOMI_PRO15_RESUME,
ALC285_FIXUP_LEGION_Y9000X_SPEAKERS,
ALC285_FIXUP_LEGION_Y9000X_AUTOMUTE,
ALC287_FIXUP_LEGION_16ACHG6,
@@ -4123,6 +4153,7 @@ enum {
ALC245_FIXUP_CS35L41_I2C_2_MUTE_LED,
ALC236_FIXUP_HP_DMIC,
ALC256_FIXUP_HONOR_MRB_XXX_M1020_AUDIO,
+ ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX,
};
/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -5700,6 +5731,10 @@ static const struct hda_fixup alc269_fixups[] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc295_fixup_hp_mute_led_coefbit11,
},
+ [ALC295_FIXUP_HP_PAVILION_MUTE_LED_1B] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc295_fixup_hp_pavilion_mute_led_1b,
+ },
[ALC298_FIXUP_SAMSUNG_AMP] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc298_fixup_samsung_amp,
@@ -6240,6 +6275,10 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
},
+ [ALC256_FIXUP_XIAOMI_PRO15_RESUME] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc256_fixup_xiaomi_pro15_resume,
+ },
[ALC287_FIXUP_LEGION_16ACHG6] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc287_fixup_legion_16achg6_speakers,
@@ -6675,6 +6714,12 @@ static const struct hda_fixup alc269_fixups[] = {
{ 0x1b, 0x90170110 },
{ }
}
+ },
+ [ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cs35l41_fixup_i2c_two,
+ .chained = true,
+ .chain_id = ALC245_FIXUP_HP_X360_MUTE_LEDS
}
};
@@ -6906,6 +6951,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
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),
+ SND_PCI_QUIRK(0x103c, 0x856a, "HP Pavilion 15-cs1xxx", ALC295_FIXUP_HP_PAVILION_MUTE_LED_1B),
SND_PCI_QUIRK(0x103c, 0x85c6, "HP Pavilion x360 Convertible 14-dy1xxx", ALC295_FIXUP_HP_MUTE_LED_COEFBIT11),
SND_PCI_QUIRK(0x103c, 0x85de, "HP Envy x360 13-ar0xxx", ALC285_FIXUP_HP_ENVY_X360),
SND_PCI_QUIRK(0x103c, 0x8603, "HP Omen 17-cb0xxx", ALC285_FIXUP_HP_MUTE_LED),
@@ -7097,7 +7143,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8be6, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8be7, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8be8, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
- SND_PCI_QUIRK(0x103c, 0x8be9, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x103c, 0x8be9, "HP Envy x360 2-in-1 Laptop 15-fh0xxx", ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX),
SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8c15, "HP Spectre x360 2-in-1 Laptop 14-eu0xxx", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX),
SND_PCI_QUIRK(0x103c, 0x8c16, "HP Spectre x360 2-in-1 Laptop 16-aa0xxx", ALC245_FIXUP_HP_SPECTRE_X360_16_AA0XXX),
@@ -7629,6 +7675,10 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3801, "Lenovo Yoga9 14IAP7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
HDA_CODEC_QUIRK(0x17aa, 0x3802, "DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga Pro 9 14IRP8", ALC287_FIXUP_TAS2781_I2C),
+ /* Yoga Pro 9 16IMH9 shares PCI SSID 17aa:3811 with Legion S7 15IMH05;
+ * use codec SSID to distinguish them
+ */
+ HDA_CODEC_QUIRK(0x17aa, 0x38d6, "Lenovo Yoga Pro 9 16IMH9", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x3811, "Legion S7 15IMH05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7),
@@ -7774,6 +7824,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1d72, 0x1905, "Xiaomi Mi Laptop Pro 15", ALC256_FIXUP_XIAOMI_PRO15_RESUME),
SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC),
SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
SND_PCI_QUIRK(0x1e39, 0xca14, "MEDION NM14LNL", ALC233_FIXUP_MEDION_MTL_SPK),
diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
index c5cf45881416..7a637d6b5576 100644
--- a/sound/soc/amd/yc/acp6x-mach.c
+++ b/sound/soc/amd/yc/acp6x-mach.c
@@ -62,6 +62,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
{
.driver_data = &acp6x_card,
.matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OMEN Gaming Laptop 16-ap0xxx"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5525"),
}
@@ -483,6 +490,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
.driver_data = &acp6x_card,
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 C7VE"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Micro-Star International Co., Ltd."),
DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 C7VF"),
}
},
@@ -671,6 +685,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
{
.driver_data = &acp6x_card,
.matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_BOARD_NAME, "8E35"),
+ }
+ },
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "MECHREVO"),
DMI_MATCH(DMI_BOARD_NAME, "MRID6"),
}
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 8ab2e60f80b4..6e8ef9cd1b31 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -60,19 +60,6 @@
low before proceeding with the configuration sequence */
#define AB8500_ANC_SM_DELAY 2000
-#define AB8500_FILTER_CONTROL(xname, xcount, xmin, xmax) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
- .info = filter_control_info, \
- .get = filter_control_get, .put = filter_control_put, \
- .private_value = (unsigned long)&(struct filter_control) \
- {.count = xcount, .min = xmin, .max = xmax} }
-
-struct filter_control {
- long min, max;
- unsigned int count;
- long value[128];
-};
-
/* Sidetone states */
static const char * const enum_sid_state[] = {
"Unconfigured",
@@ -85,45 +72,13 @@ enum sid_state {
SID_FIR_CONFIGURED = 2,
};
-static const char * const enum_anc_state[] = {
- "Unconfigured",
- "Apply FIR and IIR",
- "FIR and IIR are configured",
- "Apply FIR",
- "FIR is configured",
- "Apply IIR",
- "IIR is configured"
-};
-enum anc_state {
- ANC_UNCONFIGURED = 0,
- ANC_APPLY_FIR_IIR = 1,
- ANC_FIR_IIR_CONFIGURED = 2,
- ANC_APPLY_FIR = 3,
- ANC_FIR_CONFIGURED = 4,
- ANC_APPLY_IIR = 5,
- ANC_IIR_CONFIGURED = 6
-};
-
-/* Analog microphones */
-enum amic_idx {
- AMIC_IDX_1A,
- AMIC_IDX_1B,
- AMIC_IDX_2
-};
-
/* Private data for AB8500 device-driver */
struct ab8500_codec_drvdata {
struct regmap *regmap;
struct mutex ctrl_lock;
/* Sidetone */
- long *sid_fir_values;
enum sid_state sid_status;
-
- /* ANC */
- long *anc_fir_values;
- long *anc_iir_values;
- enum anc_state anc_status;
};
static inline const char *amic_micbias_str(enum amic_micbias micbias)
@@ -1024,89 +979,6 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes_mic2_vamicx[] = {
{"MIC2 V-AMICx Enable", NULL, "V-AMIC2"},
};
-/* ANC FIR-coefficients configuration sequence */
-static void anc_fir(struct snd_soc_component *component,
- unsigned int bnk, unsigned int par, unsigned int val)
-{
- if (par == 0 && bnk == 0)
- snd_soc_component_update_bits(component, AB8500_ANCCONF1,
- BIT(AB8500_ANCCONF1_ANCFIRUPDATE),
- BIT(AB8500_ANCCONF1_ANCFIRUPDATE));
-
- snd_soc_component_write(component, AB8500_ANCCONF5, val >> 8 & 0xff);
- snd_soc_component_write(component, AB8500_ANCCONF6, val & 0xff);
-
- if (par == AB8500_ANC_FIR_COEFFS - 1 && bnk == 1)
- snd_soc_component_update_bits(component, AB8500_ANCCONF1,
- BIT(AB8500_ANCCONF1_ANCFIRUPDATE), 0);
-}
-
-/* ANC IIR-coefficients configuration sequence */
-static void anc_iir(struct snd_soc_component *component, unsigned int bnk,
- unsigned int par, unsigned int val)
-{
- if (par == 0) {
- if (bnk == 0) {
- snd_soc_component_update_bits(component, AB8500_ANCCONF1,
- BIT(AB8500_ANCCONF1_ANCIIRINIT),
- BIT(AB8500_ANCCONF1_ANCIIRINIT));
- usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY*2);
- snd_soc_component_update_bits(component, AB8500_ANCCONF1,
- BIT(AB8500_ANCCONF1_ANCIIRINIT), 0);
- usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY*2);
- } else {
- snd_soc_component_update_bits(component, AB8500_ANCCONF1,
- BIT(AB8500_ANCCONF1_ANCIIRUPDATE),
- BIT(AB8500_ANCCONF1_ANCIIRUPDATE));
- }
- } else if (par > 3) {
- snd_soc_component_write(component, AB8500_ANCCONF7, 0);
- snd_soc_component_write(component, AB8500_ANCCONF8, val >> 16 & 0xff);
- }
-
- snd_soc_component_write(component, AB8500_ANCCONF7, val >> 8 & 0xff);
- snd_soc_component_write(component, AB8500_ANCCONF8, val & 0xff);
-
- if (par == AB8500_ANC_IIR_COEFFS - 1 && bnk == 1)
- snd_soc_component_update_bits(component, AB8500_ANCCONF1,
- BIT(AB8500_ANCCONF1_ANCIIRUPDATE), 0);
-}
-
-/* ANC IIR-/FIR-coefficients configuration sequence */
-static void anc_configure(struct snd_soc_component *component,
- bool apply_fir, bool apply_iir)
-{
- struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
- unsigned int bnk, par, val;
-
- dev_dbg(component->dev, "%s: Enter.\n", __func__);
-
- if (apply_fir)
- snd_soc_component_update_bits(component, AB8500_ANCCONF1,
- BIT(AB8500_ANCCONF1_ENANC), 0);
-
- snd_soc_component_update_bits(component, AB8500_ANCCONF1,
- BIT(AB8500_ANCCONF1_ENANC), BIT(AB8500_ANCCONF1_ENANC));
-
- if (apply_fir)
- for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++)
- for (par = 0; par < AB8500_ANC_FIR_COEFFS; par++) {
- val = snd_soc_component_read(component,
- drvdata->anc_fir_values[par]);
- anc_fir(component, bnk, par, val);
- }
-
- if (apply_iir)
- for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++)
- for (par = 0; par < AB8500_ANC_IIR_COEFFS; par++) {
- val = snd_soc_component_read(component,
- drvdata->anc_iir_values[par]);
- anc_iir(component, bnk, par, val);
- }
-
- dev_dbg(component->dev, "%s: Exit.\n", __func__);
-}
-
/*
* Control-events
*/
@@ -1130,7 +1002,7 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
- unsigned int param, sidconf, val;
+ unsigned int param, sidconf;
int status = 1;
dev_dbg(component->dev, "%s: Enter\n", __func__);
@@ -1159,9 +1031,8 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
snd_soc_component_write(component, AB8500_SIDFIRADR, 0);
for (param = 0; param < AB8500_SID_FIR_COEFFS; param++) {
- val = snd_soc_component_read(component, drvdata->sid_fir_values[param]);
- snd_soc_component_write(component, AB8500_SIDFIRCOEF1, val >> 8 & 0xff);
- snd_soc_component_write(component, AB8500_SIDFIRCOEF2, val & 0xff);
+ snd_soc_component_write(component, AB8500_SIDFIRCOEF1, 0);
+ snd_soc_component_write(component, AB8500_SIDFIRCOEF2, 0);
}
snd_soc_component_update_bits(component, AB8500_SIDFIRADR,
@@ -1180,136 +1051,6 @@ out:
return status;
}
-static int anc_status_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
-
- mutex_lock(&drvdata->ctrl_lock);
- ucontrol->value.enumerated.item[0] = drvdata->anc_status;
- mutex_unlock(&drvdata->ctrl_lock);
-
- return 0;
-}
-
-static int anc_status_control_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_component_to_dapm(component);
- struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
- struct device *dev = component->dev;
- bool apply_fir, apply_iir;
- unsigned int req;
- int status;
-
- dev_dbg(dev, "%s: Enter.\n", __func__);
-
- mutex_lock(&drvdata->ctrl_lock);
-
- req = ucontrol->value.enumerated.item[0];
- if (req >= ARRAY_SIZE(enum_anc_state)) {
- status = -EINVAL;
- goto cleanup;
- }
- if (req != ANC_APPLY_FIR_IIR && req != ANC_APPLY_FIR &&
- req != ANC_APPLY_IIR) {
- dev_err(dev, "%s: ERROR: Unsupported status to set '%s'!\n",
- __func__, enum_anc_state[req]);
- status = -EINVAL;
- goto cleanup;
- }
- apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR;
- apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR;
-
- status = snd_soc_dapm_force_enable_pin(dapm, "ANC Configure Input");
- if (status < 0) {
- dev_err(dev,
- "%s: ERROR: Failed to enable power (status = %d)!\n",
- __func__, status);
- goto cleanup;
- }
- snd_soc_dapm_sync(dapm);
-
- anc_configure(component, apply_fir, apply_iir);
-
- if (apply_fir) {
- if (drvdata->anc_status == ANC_IIR_CONFIGURED)
- drvdata->anc_status = ANC_FIR_IIR_CONFIGURED;
- else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED)
- drvdata->anc_status = ANC_FIR_CONFIGURED;
- }
- if (apply_iir) {
- if (drvdata->anc_status == ANC_FIR_CONFIGURED)
- drvdata->anc_status = ANC_FIR_IIR_CONFIGURED;
- else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED)
- drvdata->anc_status = ANC_IIR_CONFIGURED;
- }
-
- status = snd_soc_dapm_disable_pin(dapm, "ANC Configure Input");
- snd_soc_dapm_sync(dapm);
-
-cleanup:
- mutex_unlock(&drvdata->ctrl_lock);
-
- if (status < 0)
- dev_err(dev, "%s: Unable to configure ANC! (status = %d)\n",
- __func__, status);
-
- dev_dbg(dev, "%s: Exit.\n", __func__);
-
- return (status < 0) ? status : 1;
-}
-
-static int filter_control_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct filter_control *fc =
- (struct filter_control *)kcontrol->private_value;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
- uinfo->count = fc->count;
- uinfo->value.integer.min = fc->min;
- uinfo->value.integer.max = fc->max;
-
- return 0;
-}
-
-static int filter_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ab8500_codec_drvdata *drvdata = snd_soc_component_get_drvdata(component);
- struct filter_control *fc =
- (struct filter_control *)kcontrol->private_value;
- unsigned int i;
-
- mutex_lock(&drvdata->ctrl_lock);
- for (i = 0; i < fc->count; i++)
- ucontrol->value.integer.value[i] = fc->value[i];
- mutex_unlock(&drvdata->ctrl_lock);
-
- return 0;
-}
-
-static int filter_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ab8500_codec_drvdata *drvdata = snd_soc_component_get_drvdata(component);
- struct filter_control *fc =
- (struct filter_control *)kcontrol->private_value;
- unsigned int i;
-
- mutex_lock(&drvdata->ctrl_lock);
- for (i = 0; i < fc->count; i++)
- fc->value[i] = ucontrol->value.integer.value[i];
- mutex_unlock(&drvdata->ctrl_lock);
-
- return 0;
-}
-
/*
* Controls - Non-DAPM ASoC
*/
@@ -1597,7 +1338,6 @@ static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomast,
static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_sidstate, enum_sid_state);
/* ANC */
-static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_ancstate, enum_anc_state);
static struct snd_kcontrol_new ab8500_ctrls[] = {
/* Charge pump */
@@ -1873,8 +1613,6 @@ static struct snd_kcontrol_new ab8500_ctrls[] = {
AB8500_FIFOCONF6_BFIFOSAMPLE_MAX, 0),
/* ANC */
- SOC_ENUM_EXT("ANC Status", soc_enum_ancstate,
- anc_status_control_get, anc_status_control_put),
SOC_SINGLE_XR_SX("ANC Warp Delay Shift",
AB8500_ANCCONF2, 1, AB8500_ANCCONF2_SHIFT,
AB8500_ANCCONF2_MIN, AB8500_ANCCONF2_MAX, 0),
@@ -1895,21 +1633,6 @@ static struct snd_kcontrol_new ab8500_ctrls[] = {
AB8500_SIDFIRADR, AB8500_SIDFIRADR_FIRSIDSET, 0),
};
-static struct snd_kcontrol_new ab8500_filter_controls[] = {
- AB8500_FILTER_CONTROL("ANC FIR Coefficients", AB8500_ANC_FIR_COEFFS,
- AB8500_ANC_FIR_COEFF_MIN, AB8500_ANC_FIR_COEFF_MAX),
- AB8500_FILTER_CONTROL("ANC IIR Coefficients", AB8500_ANC_IIR_COEFFS,
- AB8500_ANC_IIR_COEFF_MIN, AB8500_ANC_IIR_COEFF_MAX),
- AB8500_FILTER_CONTROL("Sidetone FIR Coefficients",
- AB8500_SID_FIR_COEFFS, AB8500_SID_FIR_COEFF_MIN,
- AB8500_SID_FIR_COEFF_MAX)
-};
-enum ab8500_filter {
- AB8500_FILTER_ANC_FIR = 0,
- AB8500_FILTER_ANC_IIR = 1,
- AB8500_FILTER_SID_FIR = 2,
-};
-
/*
* Extended interface for codec-driver
*/
@@ -2454,7 +2177,6 @@ static int ab8500_codec_probe(struct snd_soc_component *component)
struct device_node *np = dev->of_node;
struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
struct ab8500_codec_platform_data codec_pdata;
- struct filter_control *fc;
int status;
dev_dbg(dev, "%s: Enter.\n", __func__);
@@ -2486,25 +2208,6 @@ static int ab8500_codec_probe(struct snd_soc_component *component)
snd_soc_component_write(component, AB8500_SHORTCIRCONF,
BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
- /* Add filter controls */
- status = snd_soc_add_component_controls(component, ab8500_filter_controls,
- ARRAY_SIZE(ab8500_filter_controls));
- if (status < 0) {
- dev_err(dev,
- "%s: failed to add ab8500 filter controls (%d).\n",
- __func__, status);
- return status;
- }
- fc = (struct filter_control *)
- ab8500_filter_controls[AB8500_FILTER_ANC_FIR].private_value;
- drvdata->anc_fir_values = (long *)fc->value;
- fc = (struct filter_control *)
- ab8500_filter_controls[AB8500_FILTER_ANC_IIR].private_value;
- drvdata->anc_iir_values = (long *)fc->value;
- fc = (struct filter_control *)
- ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value;
- drvdata->sid_fir_values = (long *)fc->value;
-
snd_soc_dapm_disable_pin(dapm, "ANC Configure Input");
mutex_init(&drvdata->ctrl_lock);
@@ -2538,7 +2241,6 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev)
if (!drvdata)
return -ENOMEM;
drvdata->sid_status = SID_UNCONFIGURED;
- drvdata->anc_status = ANC_UNCONFIGURED;
dev_set_drvdata(&pdev->dev, drvdata);
drvdata->regmap = devm_regmap_init(&pdev->dev, NULL, &pdev->dev,
diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c
index 033e56d5e9db..795e2764d67e 100644
--- a/sound/soc/codecs/cs35l56-shared.c
+++ b/sound/soc/codecs/cs35l56-shared.c
@@ -851,9 +851,11 @@ out_sync:
err:
regcache_cache_only(cs35l56_base->regmap, true);
- regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
- cs35l56_hibernate_seq,
- ARRAY_SIZE(cs35l56_hibernate_seq));
+ if (cs35l56_base->can_hibernate) {
+ regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
+ cs35l56_hibernate_seq,
+ ARRAY_SIZE(cs35l56_hibernate_seq));
+ }
return ret;
}
@@ -1728,8 +1730,7 @@ int cs35l56_read_onchip_spkid(struct cs35l56_base *cs35l56_base)
ret = regmap_read(regmap, CS35L56_GPIO_STATUS1, &val);
if (ret) {
- dev_err(cs35l56_base->dev, "GPIO%d status read failed: %d\n",
- cs35l56_base->onchip_spkid_gpios[i] + 1, ret);
+ dev_err(cs35l56_base->dev, "GPIO status read failed: %d\n", ret);
return ret;
}
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 378017fcea10..849d70ca23d6 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -1956,9 +1956,9 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
goto err;
}
- ret = devm_snd_soc_register_component(cs35l56->base.dev,
- &soc_component_dev_cs35l56,
- cs35l56_dai, ARRAY_SIZE(cs35l56_dai));
+ ret = snd_soc_register_component(cs35l56->base.dev,
+ &soc_component_dev_cs35l56,
+ cs35l56_dai, ARRAY_SIZE(cs35l56_dai));
if (ret < 0) {
dev_err_probe(cs35l56->base.dev, ret, "Register codec failed\n");
goto err;
@@ -1970,6 +1970,9 @@ err:
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies);
+ if (cs35l56->dsp_wq)
+ destroy_workqueue(cs35l56->dsp_wq);
+
return ret;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_common_probe, "SND_SOC_CS35L56_CORE");
@@ -2057,6 +2060,8 @@ EXPORT_SYMBOL_NS_GPL(cs35l56_init, "SND_SOC_CS35L56_CORE");
void cs35l56_remove(struct cs35l56_private *cs35l56)
{
+ snd_soc_unregister_component(cs35l56->base.dev);
+
cs35l56->base.init_done = false;
/*
diff --git a/sound/soc/codecs/tas2764.c b/sound/soc/codecs/tas2764.c
index 6aab6d2b7419..55211266927d 100644
--- a/sound/soc/codecs/tas2764.c
+++ b/sound/soc/codecs/tas2764.c
@@ -684,18 +684,33 @@ static int tas2764_read_die_temp(struct tas2764_priv *tas2764, long *result)
* As per datasheet, subtract 93 from raw value to get degrees
* Celsius. hwmon wants millidegrees.
*
- * NOTE: The chip will initialise the TAS2764_TEMP register to
- * 2.6 *C to avoid triggering temperature protection. Since the
- * ADC is powered down during software shutdown, this value will
- * persist until the chip is fully powered up (e.g. the PCM it's
- * attached to is opened). The ADC will power down again when
- * the chip is put back into software shutdown, with the last
- * value sampled persisting in the ADC's register.
+ * NOTE: The TAS2764 datasheet mentions initialising TAS2764_TEMP
+ * such that the temperature is 2.6 *C, however the register
+ * is actually initialised to 0. The ADC is also powered down during
+ * software shutdown. The last sampled temperature will persist
+ * in the register while the amp is in this power state.
*/
+ if (reg == 0)
+ return -ENODATA;
+
*result = (reg - 93) * 1000;
return 0;
}
+static int tas2764_hwmon_is_fault(struct tas2764_priv *tas2764, long *result)
+{
+ int ret;
+ long temp;
+
+ ret = tas2764_read_die_temp(tas2764, &temp);
+ if (ret == -ENODATA) {
+ *result = true;
+ return 0;
+ }
+
+ return ret;
+}
+
static umode_t tas2764_hwmon_is_visible(const void *data,
enum hwmon_sensor_types type, u32 attr,
int channel)
@@ -705,6 +720,7 @@ static umode_t tas2764_hwmon_is_visible(const void *data,
switch (attr) {
case hwmon_temp_input:
+ case hwmon_temp_fault:
return 0444;
default:
break;
@@ -724,6 +740,9 @@ static int tas2764_hwmon_read(struct device *dev,
case hwmon_temp_input:
ret = tas2764_read_die_temp(tas2764, val);
break;
+ case hwmon_temp_fault:
+ ret = tas2764_hwmon_is_fault(tas2764, val);
+ break;
default:
ret = -EOPNOTSUPP;
break;
@@ -733,7 +752,7 @@ static int tas2764_hwmon_read(struct device *dev,
}
static const struct hwmon_channel_info *const tas2764_hwmon_info[] = {
- HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_FAULT),
NULL
};
diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c
index 50501bcbe916..dbda9f327535 100644
--- a/sound/soc/codecs/tas2770.c
+++ b/sound/soc/codecs/tas2770.c
@@ -633,10 +633,27 @@ static int tas2770_read_die_temp(struct tas2770_priv *tas2770, long *result)
* value read back from its registers will be the last value sampled
* before entering software shutdown.
*/
+ if (reading == 0)
+ return -ENODATA;
+
*result = (reading - (93 * 16)) * 1000 / 16;
return 0;
}
+static int tas2770_hwmon_is_fault(struct tas2770_priv *tas2770, long *result)
+{
+ int ret;
+ long temp;
+
+ ret = tas2770_read_die_temp(tas2770, &temp);
+ if (ret == -ENODATA) {
+ *result = true;
+ return 0;
+ }
+
+ return ret;
+}
+
static umode_t tas2770_hwmon_is_visible(const void *data,
enum hwmon_sensor_types type, u32 attr,
int channel)
@@ -646,6 +663,7 @@ static umode_t tas2770_hwmon_is_visible(const void *data,
switch (attr) {
case hwmon_temp_input:
+ case hwmon_temp_fault:
return 0444;
default:
break;
@@ -665,6 +683,9 @@ static int tas2770_hwmon_read(struct device *dev,
case hwmon_temp_input:
ret = tas2770_read_die_temp(tas2770, val);
break;
+ case hwmon_temp_fault:
+ ret = tas2770_hwmon_is_fault(tas2770, val);
+ break;
default:
ret = -EOPNOTSUPP;
break;
@@ -674,7 +695,7 @@ static int tas2770_hwmon_read(struct device *dev,
}
static const struct hwmon_channel_info *const tas2770_hwmon_info[] = {
- HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+ HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_FAULT),
NULL
};
diff --git a/sound/soc/codecs/wm_adsp_fw_find_test.c b/sound/soc/codecs/wm_adsp_fw_find_test.c
index d0c7fb30a95d..ae686dc4fa94 100644
--- a/sound/soc/codecs/wm_adsp_fw_find_test.c
+++ b/sound/soc/codecs/wm_adsp_fw_find_test.c
@@ -45,6 +45,34 @@ struct wm_adsp_fw_find_test_params {
/* Dummy struct firmware to return from wm_adsp_request_firmware_files */
static const struct firmware wm_adsp_find_test_dummy_firmware;
+static void wm_adsp_fw_find_test_release_firmware_files_stub(struct wm_adsp_fw_files *fw)
+{
+ /*
+ * fw->wmfw.firmware and fw->coeff.firmware allocated by this KUnit
+ * test are dummies not allocated by the real request_firmware() call
+ * so they must not be passed to release_firmware().
+ * This function replaces wm_adsp_release_firmware_files().
+ */
+
+ if (!fw)
+ return;
+
+ kfree(fw->wmfw.filename);
+ kfree(fw->coeff.filename);
+
+ fw->wmfw.firmware = NULL;
+ fw->coeff.firmware = NULL;
+ fw->wmfw.filename = NULL;
+ fw->coeff.filename = NULL;
+}
+
+static void wm_adsp_free_found_fw(struct kunit *test)
+{
+ struct wm_adsp_fw_find_test *priv = test->priv;
+
+ wm_adsp_fw_find_test_release_firmware_files_stub(&priv->found_fw);
+}
+
/* Simple lookup of a filename in a list of names */
static int wm_adsp_fw_find_test_firmware_request_simple_stub(const struct firmware **firmware,
const char *filename,
@@ -97,9 +125,14 @@ static void wm_adsp_fw_find_test_pick_file(struct kunit *test)
kunit_activate_static_stub(test,
wm_adsp_firmware_request,
wm_adsp_fw_find_test_firmware_request_simple_stub);
+ kunit_activate_static_stub(test,
+ wm_adsp_release_firmware_files,
+ wm_adsp_fw_find_test_release_firmware_files_stub);
ret = wm_adsp_request_firmware_files(dsp, &priv->found_fw);
kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
+ kunit_deactivate_static_stub(test, wm_adsp_release_firmware_files);
+
KUNIT_EXPECT_EQ_MSG(test, ret,
(params->expect_wmfw || params->expect_bin) ? 0 : -ENOENT,
"%s\n", priv->searched_fw_files);
@@ -173,10 +206,13 @@ static void wm_adsp_fw_find_test_search_order(struct kunit *test)
kunit_activate_static_stub(test,
wm_adsp_firmware_request,
wm_adsp_fw_find_test_firmware_request_stub);
+ kunit_activate_static_stub(test,
+ wm_adsp_release_firmware_files,
+ wm_adsp_fw_find_test_release_firmware_files_stub);
wm_adsp_request_firmware_files(dsp, &priv->found_fw);
-
kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
+ kunit_deactivate_static_stub(test, wm_adsp_release_firmware_files);
KUNIT_EXPECT_STREQ(test, priv->searched_fw_files, params->expected_searches);
@@ -201,6 +237,7 @@ static void wm_adsp_fw_find_test_find_firmware_byindex(struct kunit *test)
dsp->cs_dsp.name = "cs1234";
dsp->part = "dsp1";
+
for (dsp->fw = 0;; dsp->fw++) {
fw_name = wm_adsp_get_fwf_name_by_index(dsp->fw);
if (!fw_name)
@@ -209,14 +246,22 @@ static void wm_adsp_fw_find_test_find_firmware_byindex(struct kunit *test)
kunit_activate_static_stub(test,
wm_adsp_firmware_request,
wm_adsp_fw_find_test_firmware_request_stub);
+ kunit_activate_static_stub(test,
+ wm_adsp_release_firmware_files,
+ wm_adsp_fw_find_test_release_firmware_files_stub);
wm_adsp_request_firmware_files(dsp, &priv->found_fw);
+
kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
+ kunit_deactivate_static_stub(test, wm_adsp_release_firmware_files);
KUNIT_EXPECT_NOT_NULL_MSG(test,
strstr(priv->searched_fw_files, fw_name),
"fw#%d Did not find '%s' in '%s'\n",
dsp->fw, fw_name, priv->searched_fw_files);
+
+ wm_adsp_free_found_fw(test);
+ memset(priv->searched_fw_files, 0, sizeof(priv->searched_fw_files));
}
}
@@ -255,15 +300,7 @@ static int wm_adsp_fw_find_test_case_init(struct kunit *test)
static void wm_adsp_fw_find_test_case_exit(struct kunit *test)
{
- struct wm_adsp_fw_find_test *priv = test->priv;
-
- /*
- * priv->found_wmfw_firmware and priv->found_bin_firmware are
- * dummies not allocated by the real request_firmware() call they
- * must not be passed to release_firmware().
- */
- kfree(priv->found_fw.wmfw.filename);
- kfree(priv->found_fw.coeff.filename);
+ wm_adsp_free_found_fw(test);
}
static void wm_adsp_fw_find_test_param_desc(const struct wm_adsp_fw_find_test_params *param,
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
index ee16cf681488..6677d3bf36ec 100644
--- a/sound/soc/fsl/fsl_xcvr.c
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -228,10 +228,14 @@ static int fsl_xcvr_capds_put(struct snd_kcontrol *kcontrol,
{
struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
+ int changed;
- memcpy(xcvr->cap_ds, ucontrol->value.bytes.data, FSL_XCVR_CAPDS_SIZE);
+ changed = memcmp(xcvr->cap_ds, ucontrol->value.bytes.data,
+ sizeof(xcvr->cap_ds)) != 0;
+ memcpy(xcvr->cap_ds, ucontrol->value.bytes.data,
+ sizeof(xcvr->cap_ds));
- return 0;
+ return changed;
}
static struct snd_kcontrol_new fsl_xcvr_earc_capds_kctl = {
@@ -1040,10 +1044,15 @@ static int fsl_xcvr_tx_cs_put(struct snd_kcontrol *kcontrol,
{
struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
+ int changed;
- memcpy(xcvr->tx_iec958.status, ucontrol->value.iec958.status, 24);
+ changed = memcmp(xcvr->tx_iec958.status,
+ ucontrol->value.iec958.status,
+ sizeof(xcvr->tx_iec958.status)) != 0;
+ memcpy(xcvr->tx_iec958.status, ucontrol->value.iec958.status,
+ sizeof(xcvr->tx_iec958.status));
- return 0;
+ return changed;
}
static struct snd_kcontrol_new fsl_xcvr_rx_ctls[] = {
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 1637cc3f3d59..849ae876d7a4 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -1608,6 +1608,7 @@ int asoc_sdw_get_dai_type(u32 type)
switch (type) {
case SDCA_FUNCTION_TYPE_SMART_AMP:
case SDCA_FUNCTION_TYPE_SIMPLE_AMP:
+ case SDCA_FUNCTION_TYPE_COMPANION_AMP:
return SOC_SDW_DAI_TYPE_AMP;
case SDCA_FUNCTION_TYPE_SMART_MIC:
case SDCA_FUNCTION_TYPE_SIMPLE_MIC:
diff --git a/sound/soc/spacemit/k1_i2s.c b/sound/soc/spacemit/k1_i2s.c
index 43481f387c44..5420ca2aefbd 100644
--- a/sound/soc/spacemit/k1_i2s.c
+++ b/sound/soc/spacemit/k1_i2s.c
@@ -148,10 +148,6 @@ static int spacemit_i2s_hw_params(struct snd_pcm_substream *substream,
u32 val;
int ret;
- val = readl(i2s->base + SSCR);
- if (val & SSCR_SSE)
- return 0;
-
dma_data = &i2s->playback_dma_data;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@@ -199,6 +195,9 @@ static int spacemit_i2s_hw_params(struct snd_pcm_substream *substream,
}
val = readl(i2s->base + SSCR);
+ if (val & SSCR_SSE)
+ return 0;
+
val &= ~SSCR_DW_32BYTE;
val |= data_width;
writel(val, i2s->base + SSCR);
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 75f82a92ff44..2f5f62079fa4 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -592,6 +592,7 @@ static __u32 reverse_bytes(__u32 b, int len)
fallthrough;
case 2:
b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1);
+ fallthrough;
case 1:
case 0:
break;
diff --git a/sound/usb/clock.c b/sound/usb/clock.c
index 842ba5b801ea..2e0c18e35281 100644
--- a/sound/usb/clock.c
+++ b/sound/usb/clock.c
@@ -208,11 +208,18 @@ static bool uac_clock_source_is_valid_quirk(struct snd_usb_audio *chip,
}
/*
- * MOTU MicroBook IIc
- * Sample rate changes takes more than 2 seconds for this device. Clock
- * validity request returns false during that period.
+ * Quirk for older MOTU AVB / hybrid interfaces
+ *
+ * These devices take more than 2 seconds to switch sample rate or
+ * clock source. During this period the clock validity request
+ * returns false, causing ALSA to fail prematurely.
+ *
+ * Affected models (all use vendor 0x07fd):
+ * - MicroBook IIc → 0x0004
+ * - 1248, 624, 8A, UltraLite AVB, 8M, 16A, ... → 0x0005
*/
- if (chip->usb_id == USB_ID(0x07fd, 0x0004)) {
+ if (chip->usb_id == USB_ID(0x07fd, 0x0004) || /* MicroBook IIc */
+ chip->usb_id == USB_ID(0x07fd, 0x0005)) { /* 1248 / 624 / 8A / UltraLite AVB / ... */
count = 0;
while ((!ret) && (count < 50)) {
diff --git a/sound/usb/midi2.c b/sound/usb/midi2.c
index 3546ba926cb3..2785600d2312 100644
--- a/sound/usb/midi2.c
+++ b/sound/usb/midi2.c
@@ -227,7 +227,7 @@ static void kill_midi_urbs(struct snd_usb_midi2_endpoint *ep, bool suspending)
if (!ep)
return;
if (suspending)
- ep->suspended = ep->running;
+ atomic_set(&ep->suspended, atomic_read(&ep->running));
atomic_set(&ep->running, 0);
for (i = 0; i < ep->num_urbs; i++) {
if (!ep->urbs[i].urb)
@@ -1188,10 +1188,11 @@ void snd_usb_midi_v2_suspend_all(struct snd_usb_audio *chip)
static void resume_midi2_endpoint(struct snd_usb_midi2_endpoint *ep)
{
- ep->running = ep->suspended;
- if (ep->direction == STR_IN)
+ atomic_set(&ep->running, atomic_read(&ep->suspended));
+ atomic_set(&ep->suspended, 0);
+
+ if (ep->direction == STR_IN || atomic_read(&ep->running))
submit_io_urbs(ep);
- /* FIXME: does it all? */
}
void snd_usb_midi_v2_resume_all(struct snd_usb_audio *chip)
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 0b4ecc2c6bcc..17983d9774f8 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -2277,6 +2277,9 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_ALIGN_TRANSFER),
DEVICE_FLG(0x05e1, 0x0480, /* Hauppauge Woodbury */
QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x05fc, 0x0231, /* JBL Pebbles */
+ QUIRK_FLAG_MIXER_PLAYBACK_LINEAR_VOL | QUIRK_FLAG_MIXER_CAPTURE_LINEAR_VOL |
+ QUIRK_FLAG_GET_SAMPLE_RATE),
DEVICE_FLG(0x0624, 0x3d3f, /* AB13X USB Audio */
QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY),
DEVICE_FLG(0x0644, 0x8043, /* TEAC UD-501/UD-501V2/UD-503/NT-503 */
@@ -2366,6 +2369,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_IGNORE_CTL_ERROR),
DEVICE_FLG(0x152a, 0x880a, /* NeuralDSP Quad Cortex */
0), /* Doesn't have the vendor quirk which would otherwise apply */
+ DEVICE_FLG(0x1532, 0x055e, /* Razer Nommo V2 X */
+ QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE),
DEVICE_FLG(0x154e, 0x1002, /* Denon DCD-1500RE */
QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
DEVICE_FLG(0x154e, 0x1003, /* Denon DA-300USB */
@@ -2458,6 +2463,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */
QUIRK_FLAG_GENERIC_IMPLICIT_FB),
+ DEVICE_FLG(0x2b73, 0x0047, /* AlphaTheta EUPHONIA */
+ QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
DEVICE_FLG(0x2d95, 0x8011, /* VIVO USB-C HEADSET */
QUIRK_FLAG_CTL_MSG_DELAY_1M),
DEVICE_FLG(0x2d95, 0x8021, /* VIVO USB-C-XE710 HEADSET */