From: Mark Brown <broonie@kernel.org>
To: Daniel Beer <daniel.beer@igorinstitute.com>
Cc: alsa-devel@alsa-project.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Andy Liu <andy-liu@ti.com>,
Derek Simkowiak <derek.simkowiak@igorinstitute.com>,
Rob Herring <robh+dt@kernel.org>,
Liam Girdwood <lgirdwood@gmail.com>
Subject: Re: [PATCH 1/2] ASoC: add support for TAS5805M digital amplifier
Date: Tue, 11 Jan 2022 17:13:11 +0000 [thread overview]
Message-ID: <Yd26p8rF3arufd2R@sirena.org.uk> (raw)
In-Reply-To: <61dccc59.1c69fb81.e1d98.02e3@mx.google.com>
[-- Attachment #1: Type: text/plain, Size: 4805 bytes --]
On Tue, Jan 11, 2022 at 12:53:11PM +1300, Daniel Beer wrote:
> +++ b/sound/soc/codecs/tas5805m.c
> @@ -0,0 +1,534 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Driver for the TAS5805M Audio Amplifier
> + *
Please make the entire comment a C++ one so things look more
intentional.
> +static void tas5805m_refresh_unlocked(struct snd_soc_component *component)
> +{
> + struct tas5805m_priv *tas5805m =
> + snd_soc_component_get_drvdata(component);
> + uint8_t v[4];
> + unsigned int i;
> + uint32_t x;
> + snd_soc_component_write(component, REG_PAGE, 0x00);
> + snd_soc_component_write(component, REG_BOOK, 0x8c);
> + snd_soc_component_write(component, REG_PAGE, 0x2a);
This isn't using the regmap paging support and I'm not seeing anything
that resets the page here.
> + for (i = 0; i < 4; i++)
> + snd_soc_component_write(component, 0x24 + i, v[i]);
> + for (i = 0; i < 4; i++)
> + snd_soc_component_write(component, 0x28 + i, v[i]);
This looks like it's potentially a stereo control but we're not allowing
the two channels to be configured separately?
> + /* Volume controls */
> + snd_soc_component_write(component, REG_DEVICE_CTRL_2,
> + tas5805m->is_muted ? 0x0b : 0x03);
This comment doesn't seem terribly descriptive and this is very much a
magic number.
> +static int tas5805m_vol_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + struct snd_soc_component *component =
> + snd_soc_kcontrol_component(kcontrol);
> + struct tas5805m_priv *tas5805m =
> + snd_soc_component_get_drvdata(component);
> +
> + mutex_lock(&tas5805m->lock);
> + ucontrol->value.integer.value[0] = tas5805m->vol;
> + mutex_unlock(&tas5805m->lock);
What is this lock intended to protect? We take the lock, do a read of a
single value and then unlock which doesn't seem like it's adding a huge
amount.
> +
> + mutex_lock(&tas5805m->lock);
> + tas5805m->vol = clamp((int)ucontrol->value.integer.value[0],
> + TAS5805M_VOLUME_MIN, TAS5805M_VOLUME_MAX);
It would be better to reject out of bounds values with an error.
> +static void send_cfg(struct snd_soc_component *component,
> + const uint8_t *s, unsigned int len)
> +{
> + unsigned int i;
> +
> + for (i = 0; i + 1 < len; i += 2)
> + snd_soc_component_write(component, s[i], s[i + 1]);
This looks like the driver might be happier using regmap directly, this
looks like an open coded _multi_reg_write().
> +/* The TAS5805M can't be configured or brought out of power-down without
> + * an I2S clock. In power-down, registers are reset.
> + *
> + * We rely on DAPM not powering up the DAC widget until the source for
> + * it is ready, which we think implies that the I2S clock is present and
> + * stable.
> + */
That's not true, we run DAPM in prepare() prior to calling trigger() and
controllers might not start clocking the bus until trigger() has been
called. There was some other device with similar issues which was
scheduling things from the trigger() callback IIRC, if you search around
in the CODEC directory you should be able to find something.
> + dev_set_drvdata(dev, tas5805m);
> + tas5805m->regmap = regmap;
> + tas5805m->gpio_pdn_n = of_get_named_gpio(dev->of_node, "pdn-gpio", 0);
> + if (!gpio_is_valid(tas5805m->gpio_pdn_n)) {
> + dev_err(dev, "power-down GPIO not specified\n");
> + return -EINVAL;
> + }
Use the gpiod APIs, you shouldn't need to do anything specific to OF
here. Also GPIO properties need to have names ending -gpios even if
they're for a single GPIO.
> + ret = devm_snd_soc_register_component(dev, &soc_codec_dev_tas5805m,
> + &tas5805m_dai, 1);
> + if (ret < 0) {
> + dev_err(dev, "unable to register codec: %d\n", ret);
> + return ret;
> + }
> +
> + ret = regulator_enable(tas5805m->pvdd);
> + if (ret < 0) {
> + dev_err(dev, "failed to enable pvdd: %d\n", ret);
> + return ret;
> + }
> +
> + usleep_range(100000, 150000);
> + gpio_set_value(tas5805m->gpio_pdn_n, 1);
> + usleep_range(10000, 15000);
This seems broken - the card might be instantiated and userspace start
using it as soon as the component is registered but we don't power on
the device until after registering it and there's no runtime power up or
down. For power management like this you need to complete the initial
power on prior to registering the component.
> +static int tas5805m_i2c_remove(struct i2c_client *i2c)
> +{
> + struct tas5805m_priv *tas5805m = dev_get_drvdata(&i2c->dev);
> +
> + gpio_set_value(tas5805m->gpio_pdn_n, 0);
> + usleep_range(10000, 15000);
> + regulator_disable(tas5805m->pvdd);
This will power down the device prior to unregistering the component so
userspace could still be running. You need to not use devm_ for
component registration and manually unregister here to avoid that issue
(or register a custom devm action).
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
next prev parent reply other threads:[~2022-01-11 17:13 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-10 23:53 Daniel Beer
2022-01-11 17:13 ` Mark Brown [this message]
2022-01-11 19:28 ` Daniel Beer
2022-01-12 20:26 ` 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=Yd26p8rF3arufd2R@sirena.org.uk \
--to=broonie@kernel.org \
--cc=alsa-devel@alsa-project.org \
--cc=andy-liu@ti.com \
--cc=daniel.beer@igorinstitute.com \
--cc=derek.simkowiak@igorinstitute.com \
--cc=devicetree@vger.kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=robh+dt@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome