All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Brown <broonie@kernel.org>
To: James Calligeros <jcalligeros99@gmail.com>
Cc: "Martin Povišer" <povik+lin@cutebit.org>,
	"Liam Girdwood" <lgirdwood@gmail.com>,
	"Rob Herring" <robh@kernel.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"Sven Peter" <sven@kernel.org>, "Janne Grunau" <j@jannau.net>,
	"Neal Gompa" <neal@gompa.dev>,
	"David Rhodes" <david.rhodes@cirrus.com>,
	"Richard Fitzgerald" <rf@opensource.cirrus.com>,
	"Jaroslav Kysela" <perex@perex.cz>,
	"Takashi Iwai" <tiwai@suse.com>, "Ulf Hansson" <ulfh@kernel.org>,
	"Amit Kucheria" <amit.kucheria@linaro.org>,
	"Rafael J. Wysocki" <rafael.j.wysocki@intel.com>,
	"Lars-Peter Clausen" <lars@metafoo.de>,
	"Vinod Koul" <vkoul@kernel.org>,
	"Matthias Brugger" <matthias.bgg@gmail.com>,
	"AngeloGioacchino Del Regno"
	<angelogioacchino.delregno@collabora.com>,
	"Shenghao Ding" <shenghao-ding@ti.com>,
	"Kevin Lu" <kevin-lu@ti.com>, "Baojun Xu" <baojun.xu@ti.com>,
	"Sen Wang" <sen@ti.com>,
	"James Schulman" <james.schulman@cirrus.com>,
	asahi@lists.linux.dev, linux-sound@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	patches@opensource.cirrus.com, "Takashi Iwai" <tiwai@suse.de>,
	linux-mediatek@lists.infradead.org,
	"Hector Martin" <marcan@marcan.st>,
	"Sasha Finkelstein" <k@chaosmail.tech>
Subject: Re: [PATCH 16/28] ASoC: apple: Add macaudio machine driver
Date: Tue, 22 Sep 2026 11:38:54 +0200	[thread overview]
Message-ID: <arJMrsl45g2_bLPB@sirena.co.uk> (raw)
In-Reply-To: <20260920-macaudio-v1-16-741cc20a74e5@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 9114 bytes --]

On Sun, Sep 20, 2026 at 02:53:55PM +1000, James Calligeros wrote:

> Apple Silicon Macs have a complex audio subsystem consisting
> of an I2S peripheral (MCA) and multiple codecs of various
> models and capabilities. Some machines have a basic mono
> speaker with hardware downmix, while others have a very
> intricate stereo system consisting of multiple codecs and
> drivers per L/R channel. Some machines report voice coil
> voltage and current information back to the SoC, and others
> do not. All machines have a headset jack.

> +config SND_SOC_APPLE_MACAUDIO
> +	tristate "Sound support for Apple Silicon Macs"
> +	depends on ARCH_APPLE || COMPILE_TEST
> +	select SND_SOC_APPLE_MCA
> +	select SND_SIMPLE_CARD_UTILS

Do we actually use simple-card?

> --- a/sound/soc/apple/Makefile
> +++ b/sound/soc/apple/Makefile
> @@ -2,3 +2,7 @@
>  snd-soc-apple-mca-y	:= mca.o
>  
>  obj-$(CONFIG_SND_SOC_APPLE_MCA)	+= snd-soc-apple-mca.o
> +
> +snd-soc-macaudio-objs	:= macaudio.o
> +
> +obj-$(CONFIG_SND_SOC_APPLE_MACAUDIO)	+= snd-soc-macaudio.o

Note the -y vs -objs style difference here.

> @@ -0,0 +1,1729 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * ASoC machine driver for Apple Silicon Macs
> + *

Please kep the entire comment block C++ so things look more consistent.

> +static void macaudio_vlimit_unlock(struct macaudio_snd_data *ma, bool unlock)
> +{

> +	case AMP_TAS5770:
> +		if (unlock)
> +			max = TAS5770_0DB;
> +		else
> +			max = 1; //TAS5770_DB(ma->cfg->safe_vol);
> +		break;
> +	case AMP_SN012776:
> +		if (unlock)
> +			max = SN012776_0DB;
> +		else
> +			max = 1; //SN012776_DB(ma->cfg->safe_vol);
> +		break;

What's going on with those comments?

> +static void macaudio_vlimit_update(struct macaudio_snd_data *ma)
> +{

> +
> +	/* Check that *every* limited control is locked by the same owner */
> +	list_for_each_entry(kctl, &ma->card.snd_card->controls, list) {
> +		if (!snd_soc_control_matches(kctl, volume_control_names[ma->cfg->amp]))
> +			continue;

This is used from the volume limit timeout work which doesn't hold the
controls_rwsem, userspace can add or remove user controls which would
change the list so the work needs to lock the controls list.

> +/*
> + * Parse one DPCM backend from the devicetree. This means taking one
> + * of the CPU DAIs and combining it with one or more CODEC DAIs.
> + */
> +static int macaudio_parse_of_be_dai_link(struct macaudio_snd_data *ma,
> +				struct snd_soc_dai_link *link,
> +				int be_index, int ncodecs_per_be,
> +				struct device_node *cpu,
> +				struct device_node *codec)

> +	ret = macaudio_parse_of_component(cpu, be_index, link->cpus);
> +	if (ret)
> +		return dev_err_probe(ma->card.dev, ret, "parsing CPU DAI of link '%s' at %pOF\n",
> +				     link->name, codec);

Cut'n'paste with logging the codec node.

> +static int macaudio_get_codec_idle_props(struct device_node *np,
> +					 struct ma_codec_idle *idle, int i,
> +					 int be_index, int ncodecs_per_cpu)
> +{
> +	char propname[32];
> +	int ret, sys_codec;
> +
> +	/*
> +	 * Depending on the BE index on the DAI, we need to offset our i
> +	 */
> +	sys_codec = i + (be_index * ncodecs_per_cpu);
> +
> +	snprintf(propname, 32, "dai-tdm-idle-mode-%d", sys_codec);
> +	ret = of_property_match_string(np, propname, "zero");
> +	if (!ret) {
> +		idle->idle_mode = SND_SOC_DAI_TDM_IDLE_ZERO;
> +	} else {
> +		ret = of_property_match_string(np, propname, "pulldown");
> +		if (!ret)
> +			idle->idle_mode = SND_SOC_DAI_TDM_IDLE_PULLDOWN;
> +		else
> +			return ret;
> +	}

Should we warn on unknown values?

> +static int macaudio_dpcm_hw_params(struct snd_pcm_substream *substream,
> +				   struct snd_pcm_hw_params *params)
> +{
> +	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> +	struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(rtd->card);
> +	struct macaudio_link_props *props = &ma->link_props[rtd->dai_link->id];
> +	struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
> +	struct snd_interval *rate = hw_param_interval(params,
> +						      SNDRV_PCM_HW_PARAM_RATE);
> +	int bclk_ratio = macaudio_get_runtime_bclk_ratio(substream);
> +	int i;
> +
> +	if (props->is_sense) {
> +		rate->min = rate->max = cpu_dai->symmetric_rate;
> +		return 0;
> +	}

It feels like this DAI ought to have separate ops...  Also, for the
sense link will we definitely already have a rate set up?

> +static int macaudio_be_trigger(struct snd_pcm_substream *substream, int cmd)
> +{
> +	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> +	struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(rtd->card);
> +	struct macaudio_link_props *props = &ma->link_props[rtd->dai_link->id];
> +
> +	if (props->is_speakers && substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> +		switch (cmd) {
> +		case SNDRV_PCM_TRIGGER_START:
> +		case SNDRV_PCM_TRIGGER_RESUME:
> +		case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
> +			ma->bes_active |= BIT(rtd->dai_link->id);
> +			break;
> +		case SNDRV_PCM_TRIGGER_SUSPEND:
> +		case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
> +		case SNDRV_PCM_TRIGGER_STOP:
> +			ma->bes_active &= ~BIT(rtd->dai_link->id);
> +			break;

Do we have adequate locking here, this is shared between BEs but the BEs
have their own locks?

> +static int macaudio_be_assign_tdm(struct snd_soc_pcm_runtime *rtd)
> +{

> +	for_each_rtd_codec_dais(rtd, i, dai) {

> +		if (props->codecs[i].idle_mode) {
> +			ret = snd_soc_dai_set_tdm_idle(dai, props->codecs[i].idle_mask,
> +						       0, props->codecs[i].idle_mode, 0);
> +		}
> +	}
> +
> +	return 0;

We store ret but don't pay attention to the result.

> +#define CHECK(call, pattern, value, min)                                       \
> +	{                                                                      \
> +		int ret = call(card, pattern, value);                          \
> +		int err = (ret >= 0 && ret < min) ? -ERANGE : ret;             \
> +		if (err < 0) {                                                 \
> +			dev_err(card->dev, "%s on '%s': %d\n", #call, pattern, \
> +				ret);                                          \
> +			if (please_blow_up_my_speakers < 2)                    \
> +				return err;                                    \
> +		} else {                                                       \
> +			dev_dbg(card->dev, "%s on '%s': %d hits\n", #call,     \
> +				pattern, ret);                                 \
> +		}                                                              \
> +	}
> +
> +#define CHECK_CONCAT(call, suffix, value) \
> +	{ \
> +		snprintf(buf, sizeof(buf), "%s%s", prefix, suffix); \
> +		CHECK(call, buf, value, 1); \
> +	}

This only requires one match, things might go wrong for a stereo setup.

> +static const struct snd_kcontrol_new macaudio_hp_mux =
> +	SOC_DAPM_ENUM("Headphones Playback Mux", macaudio_hp_mux_enum);

> +	SND_SOC_DAPM_SPK("Speaker (Static)", NULL),

Is this used?

> +	SND_SOC_DAPM_MUX("Headphone Playback Mux", SND_SOC_NOPM, 0, 0, &macaudio_hp_mux),

Headphone or Headphones?

> +static int macaudio_slk_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *uvalue)
> +{
> +	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
> +	struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(card);
> +
> +	if (!ma->speaker_lock_owner)
> +		return -EPERM;
> +
> +	if (uvalue->value.integer.value[0] != SPEAKER_MAGIC_VALUE)
> +		return -EINVAL;
> +
> +	/* Serves as a notification that the lock was lost at some point */
> +	if (ma->speaker_volume_was_locked) {
> +		ma->speaker_volume_was_locked = false;
> +		return -ETIMEDOUT;
> +	}
> +
> +	mutex_lock(&ma->volume_lock_mutex);

Shouldn't we take the mutex before checking (and potentially changing)
the state?  Otherwise we've got TOCTOU issues.

> +static void macaudio_slk_unlock(struct snd_kcontrol *kcontrol)
> +{
> +	struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
> +	struct macaudio_snd_data *ma = snd_soc_card_get_drvdata(card);
> +
> +	ma->speaker_lock_owner = NULL;
> +	ma->speaker_lock_timeout = 0;
> +	macaudio_vlimit_update(ma);
> +}

This seems to similarly be missing locking.

> +/*	enable	amp		speakers	stereo	gain	safe_vol */
> +struct macaudio_platform_cfg macaudio_j180_cfg = {
> +	false,	AMP_SN012776,	SPKR_1W1T,	false,	10,	-20,
> +};

These should be static, they're not used outside this file.  Probably
also const.

> +static const struct of_device_id macaudio_snd_device_id[]  = {

> +	/* j375    AID10   sn012776    15      1× 1W */
> +	{ .compatible = "apple,j375-macaudio", .data = &macaudio_j37x_j47x_cfg },

The j47x entries in the table use 20 not 15.

> +static void macaudio_snd_platform_remove(struct platform_device *pdev)
> +{
> +	struct macaudio_snd_data *ma = dev_get_drvdata(&pdev->dev);
> +
> +	cancel_delayed_work_sync(&ma->lock_timeout_work);
> +}

What ensures that lock_update_work is cancelled?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

  parent reply	other threads:[~2026-09-22  9:39 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-20  4:53 [PATCH 00/28] Add speaker and headset jack support for Apple Silicon Macs James Calligeros
2026-09-20  4:53 ` [PATCH 01/28] dt-bindings: sound: Add Apple Macs sound peripherals James Calligeros
2026-09-20  5:06   ` sashiko-bot
2026-09-20 18:45   ` Sven Peter
2026-09-21 15:02   ` Mark Brown
2026-09-21 15:22   ` Mark Brown
2026-09-23 11:35   ` Krzysztof Kozlowski
2026-09-20  4:53 ` [PATCH 02/28] ASoC: cs42l42: Fix typo James Calligeros
2026-09-21 15:25   ` Mark Brown
2026-09-20  4:53 ` [PATCH 03/28] ASoC: cs42l42: Set a faster digital ramp-up rate James Calligeros
2026-09-20  4:53 ` [PATCH 04/28] ASoC: apple: mca: Fix PD link double-frees James Calligeros
2026-09-20  4:53 ` [PATCH 05/28] alsa: pcm: Remove the qos request only if active James Calligeros
2026-09-21 15:03   ` Mark Brown
2026-09-22  8:09   ` Mark Brown
2026-09-20  4:53 ` [PATCH 06/28] ALSA: dmaengine: Always terminate DMA when a PCM is closed James Calligeros
2026-09-20  5:05   ` sashiko-bot
2026-09-22 10:12   ` Mark Brown
2026-09-20  4:53 ` [PATCH 07/28] ALSA: Support nonatomic dmaengine PCMs James Calligeros
2026-09-20  5:09   ` sashiko-bot
2026-09-21 15:32   ` Mark Brown
2026-09-20  4:53 ` [PATCH 08/28] ALSA: control: Add kcontrol callbacks for lock/unlock James Calligeros
2026-09-20  5:11   ` sashiko-bot
2026-09-29  9:52   ` Takashi Iwai
2026-10-03  1:34     ` James Calligeros
2026-10-03  6:39       ` Takashi Iwai
2026-10-03  9:22         ` Takashi Iwai
2026-09-20  4:53 ` [PATCH 09/28] ASoC: ops: Move guts out of snd_soc_limit_volume James Calligeros
2026-09-20  4:53 ` [PATCH 10/28] ASoC: ops: Accept patterns in snd_soc_limit_volume James Calligeros
2026-09-20  5:12   ` sashiko-bot
2026-09-21 15:27   ` Mark Brown
2026-09-21 16:27     ` Charles Keepax
2026-09-23 11:12       ` James Calligeros
2026-09-20  4:53 ` [PATCH 11/28] ASoC: ops: Introduce 'snd_soc_deactivate_kctl' James Calligeros
2026-09-20  5:09   ` sashiko-bot
2026-09-22  9:53   ` Mark Brown
2026-09-20  4:53 ` [PATCH 12/28] ASoC: ops: Introduce 'soc_set_enum_kctl' James Calligeros
2026-09-20  5:10   ` sashiko-bot
2026-09-22  9:50   ` Mark Brown
2026-09-20  4:53 ` [PATCH 13/28] ASoC: card: Let 'fixup_controls' return errors James Calligeros
2026-09-20  4:53 ` [PATCH 14/28] ASoC: ops: Export snd_soc_control_matches() James Calligeros
2026-09-22  9:43   ` Mark Brown
2026-09-20  4:53 ` [PATCH 15/28] ASoC: tas2764: Set up V/ISENSE on codec probe James Calligeros
2026-09-20  5:10   ` sashiko-bot
2026-09-22  9:40   ` Mark Brown
2026-09-20  4:53 ` [PATCH 16/28] ASoC: apple: Add macaudio machine driver James Calligeros
2026-09-20  5:14   ` sashiko-bot
2026-09-22  9:38   ` Mark Brown [this message]
2026-09-26  1:06     ` James Calligeros
2026-09-28 11:03       ` Mark Brown
2026-09-30  7:36         ` James Calligeros
2026-09-30 11:17           ` Mark Brown
2026-09-20  4:53 ` [PATCH 17/28] arm64: dts: apple: t8103-j274: Add speaker/headset jack nodes James Calligeros
2026-09-20  5:14   ` sashiko-bot
2026-09-20  4:53 ` [PATCH 18/28] arm64: dts: apple: t8103-j313: " James Calligeros
2026-09-20  4:53 ` [PATCH 19/28] arm64: dts: apple: t8103-j293: " James Calligeros
2026-09-20  5:19   ` sashiko-bot
2026-09-20  4:53 ` [PATCH 20/28] arm64: dts: apple: t8103-j45x: Add headset " James Calligeros
2026-09-20  5:16   ` sashiko-bot
2026-09-20  4:54 ` [PATCH 21/28] arm64: dts: apple: t8112-j413: Add speaker/headset " James Calligeros
2026-09-20  5:14   ` sashiko-bot
2026-09-20  4:54 ` [PATCH 22/28] arm64: dts: apple: t8112-j415: " James Calligeros
2026-09-20  4:54 ` [PATCH 23/28] arm64: dts: apple: t8112-j473: " James Calligeros
2026-09-20  5:19   ` sashiko-bot
2026-09-20  4:54 ` [PATCH 24/28] arm64: dts: apple: t8112-j493: " James Calligeros
2026-09-20  5:17   ` sashiko-bot
2026-09-20  4:54 ` [PATCH 25/28] arm64: dts: apple: t600x-j31x: " James Calligeros
2026-09-20  5:17   ` sashiko-bot
2026-09-20  4:54 ` [PATCH 26/28] arm64: dts: apple: t600x-j375: " James Calligeros
2026-09-20  5:16   ` sashiko-bot
2026-09-20  4:54 ` [PATCH 27/28] arm64: dts: apple: t602x-j41x: " James Calligeros
2026-09-20  4:54 ` [PATCH 28/28] arm64: dts: apple: t602x-j47x: " James Calligeros
2026-09-20  5:15   ` sashiko-bot
2026-09-21 15:14 ` [PATCH 00/28] Add speaker and headset jack support for Apple Silicon Macs Mark Brown

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=arJMrsl45g2_bLPB@sirena.co.uk \
    --to=broonie@kernel.org \
    --cc=amit.kucheria@linaro.org \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=asahi@lists.linux.dev \
    --cc=baojun.xu@ti.com \
    --cc=conor+dt@kernel.org \
    --cc=david.rhodes@cirrus.com \
    --cc=devicetree@vger.kernel.org \
    --cc=j@jannau.net \
    --cc=james.schulman@cirrus.com \
    --cc=jcalligeros99@gmail.com \
    --cc=k@chaosmail.tech \
    --cc=kevin-lu@ti.com \
    --cc=krzk+dt@kernel.org \
    --cc=lars@metafoo.de \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=marcan@marcan.st \
    --cc=matthias.bgg@gmail.com \
    --cc=neal@gompa.dev \
    --cc=patches@opensource.cirrus.com \
    --cc=perex@perex.cz \
    --cc=povik+lin@cutebit.org \
    --cc=rafael.j.wysocki@intel.com \
    --cc=rf@opensource.cirrus.com \
    --cc=robh@kernel.org \
    --cc=sen@ti.com \
    --cc=shenghao-ding@ti.com \
    --cc=sven@kernel.org \
    --cc=tiwai@suse.com \
    --cc=tiwai@suse.de \
    --cc=ulfh@kernel.org \
    --cc=vkoul@kernel.org \
    /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.