mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Will Porter <mrwillporter@gmail.com>
To: Christian Ruppert <arc@gmx.li>
Cc: Takashi Iwai <tiwai@suse.com>, Jaroslav Kysela <perex@perex.cz>,
	linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
	Neil Andrews <neil@androos.io>
Subject: [RFC PATCH 6/6] ALSA: mixer_audient: Use the same cache for the iD14 MkI FU 12 control
Date: Wed, 11 Nov 2026 20:37:20 -0600	[thread overview]
Message-ID: <20261112023720.1503814-7-mrwillporter@gmail.com> (raw)
In-Reply-To: <20261112023720.1503814-1-mrwillporter@gmail.com>

The FU 12 control keeps its own value array and valid mask on a
struct usb_mixer_elem_list. Make it a struct usb_mixer_elem_info, and
use cache_val[ch] and bit ch of cached as the other controls do. Set
channels and get_cur_broken. Remove the private struct.

The list head is the first member of struct usb_mixer_elem_info, so
snd_usb_mixer_elem_free() still frees the right pointer. The control
is still registered with is_std_info false, so the generic notify
paths do not touch it.

No functional change.

Assisted-by: Claude:claude-fable-5-2
Assisted-by: Claude:claude-sonnet-5-5
Signed-off-by: Will Porter <mrwillporter@gmail.com>
---
 sound/usb/mixer_audient.c | 54 ++++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 26 deletions(-)

diff --git a/sound/usb/mixer_audient.c b/sound/usb/mixer_audient.c
index edc568830366c..8c81a4c05995f 100644
--- a/sound/usb/mixer_audient.c
+++ b/sound/usb/mixer_audient.c
@@ -1074,26 +1074,26 @@ static const struct snd_audient_ctrl_type snd_audient_id14_fu12_type = {
 	.sel = UAC_FU_VOLUME,
 };
 
-struct snd_audient_id14_fu12 {
-	struct usb_mixer_elem_list list;	/* first: snd_usb_mixer_elem_free */
-	long val[ID14_FU12_CHANNELS];
-	u8 valid;				/* bit per channel */
-};
-
-static int snd_audient_id14_fu12_write(struct snd_audient_id14_fu12 *f,
+/*
+ * The control is a struct usb_mixer_elem_info whose list head is registered
+ * with is_std_info false. The head is the first member, as
+ * snd_usb_mixer_elem_free needs. cache_val[ch] and bit ch of cached hold
+ * the last value the device accepted.
+ */
+static int snd_audient_id14_fu12_write(struct usb_mixer_elem_info *elem,
 				       unsigned int ch, long val)
 {
 	__le16 buf = cpu_to_le16(val == ID14_FU12_MUTE ? -128 * 256
 				 : (val - ID14_FU12_MAX) * 256);
 	int ret;
 
-	ret = snd_audient_set_cur(f->list.mixer, &snd_audient_id14_fu12_type,
+	ret = snd_audient_set_cur(elem->head.mixer, &snd_audient_id14_fu12_type,
 				  ch + 1, &buf);
 	if (ret < 0)
 		return ret;
 
-	f->val[ch] = val;
-	f->valid |= BIT(ch);
+	elem->cache_val[ch] = val;
+	set_bit(ch, elem->cached);
 
 	return 0;
 }
@@ -1112,13 +1112,13 @@ static int snd_ctl_audient_id14_fu12_info(struct snd_kcontrol *kctl,
 static int snd_ctl_audient_id14_fu12_get(struct snd_kcontrol *kctl,
 					 struct snd_ctl_elem_value *ctl_val)
 {
-	struct snd_audient_id14_fu12 *f = snd_kcontrol_chip(kctl);
+	struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kctl);
 	unsigned int ch;
 
 	/* a channel that was never written reads as mute */
 	for (ch = 0; ch < ID14_FU12_CHANNELS; ch++)
-		ctl_val->value.integer.value[ch] = (f->valid & BIT(ch))
-						   ? f->val[ch]
+		ctl_val->value.integer.value[ch] = test_bit(ch, elem->cached)
+						   ? elem->cache_val[ch]
 						   : ID14_FU12_MUTE;
 
 	return 0;
@@ -1127,7 +1127,7 @@ static int snd_ctl_audient_id14_fu12_get(struct snd_kcontrol *kctl,
 static int snd_ctl_audient_id14_fu12_set(struct snd_kcontrol *kctl,
 					 struct snd_ctl_elem_value *ctl_val)
 {
-	struct snd_audient_id14_fu12 *f = snd_kcontrol_chip(kctl);
+	struct usb_mixer_elem_info *elem = snd_kcontrol_chip(kctl);
 	long *const v = ctl_val->value.integer.value;
 	unsigned int ch;
 	int changed = 0;
@@ -1136,7 +1136,7 @@ static int snd_ctl_audient_id14_fu12_set(struct snd_kcontrol *kctl,
 		if (v[ch] < 0 || v[ch] > ID14_FU12_MAX)
 			return -EINVAL;
 
-	CLASS(snd_usb_lock, pm)(f->list.mixer->chip);
+	CLASS(snd_usb_lock, pm)(elem->head.mixer->chip);
 	if (pm.err < 0)
 		return pm.err;
 
@@ -1147,10 +1147,10 @@ static int snd_ctl_audient_id14_fu12_set(struct snd_kcontrol *kctl,
 	for (ch = 0; ch < ID14_FU12_CHANNELS; ch++) {
 		int ret;
 
-		if (!(f->valid & BIT(ch)) || f->val[ch] != v[ch])
+		if (!test_bit(ch, elem->cached) || elem->cache_val[ch] != v[ch])
 			changed = 1;
 
-		ret = snd_audient_id14_fu12_write(f, ch, v[ch]);
+		ret = snd_audient_id14_fu12_write(elem, ch, v[ch]);
 		if (ret < 0)
 			return ret;
 	}
@@ -1171,19 +1171,21 @@ static int snd_audient_id14_mk1_create(struct usb_mixer_interface *mixer)
 		.put = snd_ctl_audient_id14_fu12_set,
 		.tlv.p = snd_audient_tlv_id14_fu12,
 	};
-	struct snd_audient_id14_fu12 *f;
+	struct usb_mixer_elem_info *elem;
 	struct snd_kcontrol *kctl;
 	unsigned int ch;
 
-	f = kzalloc_obj(*f);
-	if (!f)
+	elem = kzalloc_obj(*elem);
+	if (!elem)
 		return -ENOMEM;
 
-	f->list.mixer = mixer;
-	f->list.id = ID14_FU_MIX;
+	elem->head.mixer = mixer;
+	elem->head.id = ID14_FU_MIX;
+	elem->channels = ID14_FU12_CHANNELS;
+	elem->get_cur_broken = 1;
 
 	for (ch = 0; ch < ID14_FU12_CHANNELS; ch++) {
-		const int ret = snd_audient_id14_fu12_write(f, ch,
+		const int ret = snd_audient_id14_fu12_write(elem, ch,
 				ch < ID14_FU12_MAIN_CHANNELS ? ID14_FU12_MAX
 							     : ID14_FU12_MUTE);
 
@@ -1193,15 +1195,15 @@ static int snd_audient_id14_mk1_create(struct usb_mixer_interface *mixer)
 				       ch + 1, ret);
 	}
 
-	kctl = snd_ctl_new1(&knew, f);
+	kctl = snd_ctl_new1(&knew, elem);
 	if (!kctl) {
-		kfree(f);
+		kfree(elem);
 		return -ENOMEM;
 	}
 
 	kctl->private_free = snd_usb_mixer_elem_free;
 
-	return snd_usb_mixer_add_list(&f->list, kctl, false, true);
+	return snd_usb_mixer_add_list(&elem->head, kctl, false, true);
 }
 
 /* called from mixer_quirks.c */
-- 
2.47.3


      parent reply	other threads:[~2026-11-12  2:37 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <sashiko-outbox-201869@kernel.org>
2026-11-06 20:29 ` [RFC PATCH 13/16] ALSA: mixer_audient: Add enumerated controls Will Porter
2026-11-09 22:30   ` Christian Ruppert
2026-11-10  2:13     ` Will Porter
2026-11-10 20:57       ` Christian Ruppert
2026-11-12  2:37         ` [RFC PATCH 0/6] ALSA: mixer_audient: Cache rework and simplifications Will Porter
2026-11-12  2:37           ` [RFC PATCH 1/6] ALSA: mixer_audient: Fold in the review changes to patches 12-16 Will Porter
2026-11-12  2:37           ` [RFC PATCH 2/6] ALSA: mixer_audient: Use the cache of usb_mixer_elem_info Will Porter
2026-11-12  2:37           ` [RFC PATCH 3/6] ALSA: mixer_audient: Replace three flags with an access mode Will Porter
2026-11-12  2:37           ` [RFC PATCH 4/6] ALSA: mixer_audient: Fill the cache on first use Will Porter
2026-11-12  2:37           ` [RFC PATCH 5/6] ALSA: mixer_audient: Use one get and one put for all control types Will Porter
2026-11-12  2:37           ` Will Porter [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261112023720.1503814-7-mrwillporter@gmail.com \
    --to=mrwillporter@gmail.com \
    --cc=arc@gmx.li \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=neil@androos.io \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®