From: Charles Keepax <ckeepax@opensource.cirrus.com>
To: broonie@kernel.org
Cc: lgirdwood@gmail.com, yung-chuan.liao@linux.intel.com,
pierre-louis.bossart@linux.dev, peter.ujfalusi@linux.intel.com,
niranjan.hy@ti.com, kevin-lu@ti.com, baojun.xu@ti.com,
linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org,
patches@opensource.cirrus.com
Subject: [PATCH v2 1/3] ASoC: SDCA: Add correct masks whilst reporting SDCA jack status
Date: Thu, 30 Apr 2026 11:21:18 +0100 [thread overview]
Message-ID: <20260430102120.1283320-2-ckeepax@opensource.cirrus.com> (raw)
In-Reply-To: <20260430102120.1283320-1-ckeepax@opensource.cirrus.com>
Currently, all SDCA jacks simply report against a mask of 0xFFFF. This
works fine for system with a single SDCA jack control as the status
reflects that single control at all times. However, if two SDCA
jack controls exist in the system, such as a separate representation for
input and output, then the second control can cancel reports from the
other since it will only report its relevant bits and zero in all other
slots. This is exactly what the mask is for.
Build up a mask using all the possible states for an SCDA jack control
at registration time and use that mask when reporting a particular jack.
It is worth noting this still doesn't handle cases such as two headphone
jacks as that would require separate ALSA jacks to report to.
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
No changes since v1.
include/sound/sdca_jack.h | 3 ++
sound/soc/sdca/sdca_jack.c | 75 ++++++++++++++++++++++----------------
2 files changed, 47 insertions(+), 31 deletions(-)
diff --git a/include/sound/sdca_jack.h b/include/sound/sdca_jack.h
index 3ec22046d3ebc..181541f0f4d8c 100644
--- a/include/sound/sdca_jack.h
+++ b/include/sound/sdca_jack.h
@@ -18,10 +18,13 @@ struct snd_soc_jack;
* struct jack_state - Jack state structure to keep data between interrupts
* @kctl: Pointer to the ALSA control attached to this jack
* @jack: Pointer to the ASoC jack struct for this jack
+ * @mask: Possible reported jack status bits for this jack
*/
struct jack_state {
struct snd_kcontrol *kctl;
struct snd_soc_jack *jack;
+
+ unsigned int mask;
};
int sdca_jack_alloc_state(struct sdca_interrupt *interrupt);
diff --git a/sound/soc/sdca/sdca_jack.c b/sound/soc/sdca/sdca_jack.c
index 49d317d3b8c85..be2506f38c711 100644
--- a/sound/soc/sdca/sdca_jack.c
+++ b/sound/soc/sdca/sdca_jack.c
@@ -145,6 +145,32 @@ int sdca_jack_alloc_state(struct sdca_interrupt *interrupt)
}
EXPORT_SYMBOL_NS_GPL(sdca_jack_alloc_state, "SND_SOC_SDCA");
+static int type_get_mask(enum sdca_terminal_type type)
+{
+ switch (type) {
+ case SDCA_TERM_TYPE_LINEIN_STEREO:
+ case SDCA_TERM_TYPE_LINEIN_FRONT_LR:
+ case SDCA_TERM_TYPE_LINEIN_CENTER_LFE:
+ case SDCA_TERM_TYPE_LINEIN_SURROUND_LR:
+ case SDCA_TERM_TYPE_LINEIN_REAR_LR:
+ return SND_JACK_LINEIN;
+ case SDCA_TERM_TYPE_LINEOUT_STEREO:
+ case SDCA_TERM_TYPE_LINEOUT_FRONT_LR:
+ case SDCA_TERM_TYPE_LINEOUT_CENTER_LFE:
+ case SDCA_TERM_TYPE_LINEOUT_SURROUND_LR:
+ case SDCA_TERM_TYPE_LINEOUT_REAR_LR:
+ return SND_JACK_LINEOUT;
+ case SDCA_TERM_TYPE_MIC_JACK:
+ return SND_JACK_MICROPHONE;
+ case SDCA_TERM_TYPE_HEADPHONE_JACK:
+ return SND_JACK_HEADPHONE;
+ case SDCA_TERM_TYPE_HEADSET_JACK:
+ return SND_JACK_HEADSET;
+ default:
+ return 0;
+ }
+}
+
/**
* sdca_jack_set_jack - attach an ASoC jack to SDCA
* @info: SDCA interrupt information.
@@ -154,7 +180,8 @@ EXPORT_SYMBOL_NS_GPL(sdca_jack_alloc_state, "SND_SOC_SDCA");
*/
int sdca_jack_set_jack(struct sdca_interrupt_info *info, struct snd_soc_jack *jack)
{
- int i, ret;
+ int i, j;
+ int ret;
guard(mutex)(&info->irq_lock);
@@ -162,6 +189,7 @@ int sdca_jack_set_jack(struct sdca_interrupt_info *info, struct snd_soc_jack *ja
struct sdca_interrupt *interrupt = &info->irqs[i];
struct sdca_control *control = interrupt->control;
struct sdca_entity *entity = interrupt->entity;
+ struct sdca_control_range *range;
struct jack_state *jack_state;
if (!interrupt->irq)
@@ -169,9 +197,23 @@ int sdca_jack_set_jack(struct sdca_interrupt_info *info, struct snd_soc_jack *ja
switch (SDCA_CTL_TYPE(entity->type, control->sel)) {
case SDCA_CTL_TYPE_S(GE, DETECTED_MODE):
+ range = sdca_selector_find_range(interrupt->dev, entity,
+ SDCA_CTL_GE_SELECTED_MODE,
+ SDCA_SELECTED_MODE_NCOLS, 0);
+ if (!range)
+ return -EINVAL;
+
jack_state = interrupt->priv;
jack_state->jack = jack;
+ for (j = 0; j < range->rows; j++) {
+ enum sdca_terminal_type type;
+
+ type = sdca_range(range, SDCA_SELECTED_MODE_TERM_TYPE, j);
+
+ jack_state->mask |= type_get_mask(type);
+ }
+
/* Report initial state in case IRQ was already handled */
ret = sdca_jack_report(interrupt);
if (ret)
@@ -191,7 +233,6 @@ int sdca_jack_report(struct sdca_interrupt *interrupt)
struct jack_state *jack_state = interrupt->priv;
struct sdca_control_range *range;
enum sdca_terminal_type type;
- unsigned int report = 0;
unsigned int reg, val;
int ret;
@@ -213,35 +254,7 @@ int sdca_jack_report(struct sdca_interrupt *interrupt)
type = sdca_range_search(range, SDCA_SELECTED_MODE_INDEX,
val, SDCA_SELECTED_MODE_TERM_TYPE);
- switch (type) {
- case SDCA_TERM_TYPE_LINEIN_STEREO:
- case SDCA_TERM_TYPE_LINEIN_FRONT_LR:
- case SDCA_TERM_TYPE_LINEIN_CENTER_LFE:
- case SDCA_TERM_TYPE_LINEIN_SURROUND_LR:
- case SDCA_TERM_TYPE_LINEIN_REAR_LR:
- report = SND_JACK_LINEIN;
- break;
- case SDCA_TERM_TYPE_LINEOUT_STEREO:
- case SDCA_TERM_TYPE_LINEOUT_FRONT_LR:
- case SDCA_TERM_TYPE_LINEOUT_CENTER_LFE:
- case SDCA_TERM_TYPE_LINEOUT_SURROUND_LR:
- case SDCA_TERM_TYPE_LINEOUT_REAR_LR:
- report = SND_JACK_LINEOUT;
- break;
- case SDCA_TERM_TYPE_MIC_JACK:
- report = SND_JACK_MICROPHONE;
- break;
- case SDCA_TERM_TYPE_HEADPHONE_JACK:
- report = SND_JACK_HEADPHONE;
- break;
- case SDCA_TERM_TYPE_HEADSET_JACK:
- report = SND_JACK_HEADSET;
- break;
- default:
- break;
- }
-
- snd_soc_jack_report(jack_state->jack, report, 0xFFFF);
+ snd_soc_jack_report(jack_state->jack, type_get_mask(type), jack_state->mask);
return 0;
}
--
2.47.3
next prev parent reply other threads:[~2026-04-30 10:21 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-30 10:21 [PATCH v2 0/3] Improve SDCA support for duplicated features Charles Keepax
2026-04-30 10:21 ` Charles Keepax [this message]
2026-04-30 10:21 ` [PATCH v2 2/3] ASoC: SDCA: Remove sdca_function_data duplication Charles Keepax
2026-04-30 10:55 ` Mark Brown
2026-04-30 12:03 ` Charles Keepax
2026-04-30 10:21 ` [PATCH v2 3/3] ASoC: SDCA: Support devices with multiple functions of identical type Charles Keepax
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=20260430102120.1283320-2-ckeepax@opensource.cirrus.com \
--to=ckeepax@opensource.cirrus.com \
--cc=baojun.xu@ti.com \
--cc=broonie@kernel.org \
--cc=kevin-lu@ti.com \
--cc=lgirdwood@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=niranjan.hy@ti.com \
--cc=patches@opensource.cirrus.com \
--cc=peter.ujfalusi@linux.intel.com \
--cc=pierre-louis.bossart@linux.dev \
--cc=yung-chuan.liao@linux.intel.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