All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Karl Asseily" <karl@asseily.com>
Cc: conor+dt@kernel.org, devicetree@vger.kernel.org, robh@kernel.org
Subject: Re: [PATCH v3 3/4] ASoC: es9039q2m: add ESS Technology ES9039Q2M codec driver
Date: Fri, 18 Sep 2026 03:24:14 +0000	[thread overview]
Message-ID: <20260918032414.DA9E01F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260918031326.68542-4-karl@asseily.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Medium] es9039q2m: unprotected read-modify-write in es9039_wide_put
- [Medium] es9039q2m: unprotected VOLUME_HOLD sequence allows torn volume updates
- [Medium] es9039q2m: FIR coefficient RAM is lost on system suspend
- [Low] i2c: missing named initializer for struct i2c_device_id
--

commit b181df27142d5449ea7b02fc0c4c0aa3fd24e5a8
Author: Karl Asseily <karl@asseily.com>

ASoC: es9039q2m: add ESS Technology ES9039Q2M codec driver

This patch adds I2C support for the ESS Technology ES9039Q2M 32-bit
2-channel audio DAC. It includes handling for software mode over I2C,
an asynchronous sample rate converter, and automatic DoP detection.

> diff --git a/sound/soc/codecs/es9039q2m.c b/sound/soc/codecs/es9039q2m.c
> index 0000000000000..4edaab87e3f6f
> --- /dev/null
> +++ b/sound/soc/codecs/es9039q2m.c

[ ... ]

> +static int es9039_wide_put(struct snd_kcontrol *kcontrol,
> +			   struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *c = snd_kcontrol_chip(kcontrol);
> +	struct es9039q2m_priv *priv = snd_soc_component_get_drvdata(c);
> +	struct es9039_wide_ctl *p = (void *)kcontrol->private_value;
> +	long v = ucontrol->value.integer.value[0];
> +	u32 old;
> +	int ret;
> +
> +	if (v < 0 || v > p->max)
> +		return -EINVAL;
> +
> +	ret = es9039_read_le(priv->regmap, p->reg, p->bytes, &old);
> +	if (ret)
> +		return ret;
> +
> +	if ((old & p->mask) == (u32)v)
> +		return 0;
> +
> +	/* Preserve the bits outside the field - reg 124 carries MUTE_RAMP. */
> +	ret = es9039_write_le(priv->regmap, p->reg, p->bytes,
> +			      (old & ~p->mask) | (u32)v);

[Severity: Medium]
Could this manual read-modify-write sequence race with other ALSA control updates?

Because snd_ctl_elem_write() takes the ALSA controls_rwsem lock in read mode,
concurrent control writes can interleave here. If another thread updates the
"Mute Ramp To Ground Switch" (which shares register 125, mapped here) right
after es9039_read_le() completes, es9039_write_le() will overwrite and lose
that concurrent change.

Should this sequence be protected by a lock?

[ ... ]

> +static int es9039_vol_put(struct snd_kcontrol *kcontrol,
> +			  struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *c = snd_kcontrol_chip(kcontrol);
> +	struct es9039q2m_priv *priv = snd_soc_component_get_drvdata(c);
> +	int ret;
> +
> +	ret = regmap_update_bits(priv->regmap, ES9039_IIR_SPDIF,
> +				 ES9039_VOLUME_HOLD, ES9039_VOLUME_HOLD);
> +	if (ret)
> +		return ret;
> +
> +	ret = snd_soc_put_volsw(kcontrol, ucontrol);
> +
> +	regmap_update_bits(priv->regmap, ES9039_IIR_SPDIF,
> +			   ES9039_VOLUME_HOLD, 0);

[Severity: Medium]
Does this sequence need protection against concurrent volume updates?

If two threads call es9039_vol_put() concurrently, the sequences could
interleave. For example, Thread 1 could clear ES9039_VOLUME_HOLD while
Thread 2 is halfway through its snd_soc_put_volsw() writes.

Thread 2's remaining register writes would then apply immediately instead of
being latched together, which defeats the hardware pop-suppression mechanism.

[ ... ]

> +static int es9039q2m_resume(struct snd_soc_component *component)
> +{
> +	struct es9039q2m_priv *priv = snd_soc_component_get_drvdata(component);
> +	int ret;
> +
> +	guard(mutex)(&priv->lock);
> +
> +	regcache_cache_only(priv->regmap, false);
> +
> +	/*
> +	 * Mute the part before anything else, and write it straight to the
> +	 * hardware rather than through the cache.
> +	 *
> +	 * Where the board kept the supplies up this is a no-op - the part still
> +	 * holds the mute state it went to sleep with. Where the board removed
> +	 * them it is not: the part comes back at reset defaults, which are
> +	 * DAC_MODE clear, both channels UNMUTED, and both volume registers at
> +	 * 0x00, their 0 dB setting. regcache_sync() walks registers in ascending
> +	 * address order, so it would set DAC_MODE in register 0 - lighting the
> +	 * datapath up unmuted at full scale - and only restore the real mute in
> +	 * register 86, long after. That is the thump the probe path mutes to
> +	 * avoid, arriving by the other door.
> +	 *
> +	 * The cache is bypassed so the cached mute state is untouched; the sync
> +	 * below puts it back, after the volume registers at 74 and 75.
> +	 */
> +	regcache_cache_bypass(priv->regmap, true);
> +	ret = regmap_update_bits(priv->regmap, ES9039_DAC_MUTE,
> +				 ES9039_MUTE_BOTH, ES9039_MUTE_BOTH);
> +	regcache_cache_bypass(priv->regmap, false);
> +
> +	if (ret)
> +		dev_warn(component->dev,
> +			 "could not mute before resync: %d\n", ret);
> +
> +	ret = regcache_sync(priv->regmap);

[Severity: Medium]
Will the programmable FIR coefficients survive a system suspend?

If the device loses power during suspend, the FIR memory is cleared.
When resume calls regcache_sync() here, it will restore ES9039_PROG_RAM_CTRL
(which turns the custom FIR switch back on). However, the FIR taps
themselves are not restored since the data port is write-only and not
tracked by regmap.

Can this result in silent or distorted audio on resume?

[ ... ]

> +static const struct i2c_device_id es9039q2m_i2c_id[] = {
> +	{ "es9039q2m" },
> +	{ }
> +};

[Severity: Low]
Can we use named initializers for this array?

The I2C subsystem requires explicitly named initializers for struct
i2c_device_id arrays to ensure proper device matching.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260918031326.68542-1-karl@asseily.com?part=3

  reply	other threads:[~2026-09-18  3:24 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-18  3:13 [PATCH v3 0/4] ASoC: add ESS Technology ES9039Q2M codec driver Karl Asseily
2026-09-18  3:13 ` [PATCH v3 1/4] dt-bindings: vendor-prefixes: add ESS Technology Karl Asseily
2026-09-18 17:27   ` Rob Herring
2026-09-18  3:13 ` [PATCH v3 2/4] ASoC: dt-bindings: add ESS Technology ES9039Q2M Karl Asseily
2026-09-18  3:20   ` sashiko-bot
2026-09-18 17:29   ` Rob Herring
2026-09-18  3:13 ` [PATCH v3 3/4] ASoC: es9039q2m: add ESS Technology ES9039Q2M codec driver Karl Asseily
2026-09-18  3:24   ` sashiko-bot [this message]
2026-09-18 18:27     ` Karl Asseily
2026-09-18 10:46   ` Mark Brown
2026-09-18 10:59     ` Karl Asseily
2026-09-18 11:23       ` Mark Brown
2026-09-18  3:13 ` [PATCH v3 4/4] MAINTAINERS: add entry for the " Karl Asseily

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=20260918032414.DA9E01F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=karl@asseily.com \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.