[PATCH] ASoC: nau8821: Add driver for Nuvoton codec chip NAU88L21.

Mark Brown broonie at kernel.org
Fri Jul 16 20:30:04 CEST 2021


On Fri, Jul 02, 2021 at 12:35:00AM +0800, Seven Lee wrote:
> The driver is for codec NAU88L21 of Nuvoton Technology Corporation.

> --- /dev/null
> +++ b/sound/soc/codecs/nau8821.c
> @@ -0,0 +1,1781 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Nuvoton NAU88L21 audio codec driver

Please make the entire comment a C++ one so things look more
intentional.

> +/**
> + * nau8821_sema_acquire - acquire the semaphore of nau8821
> + * @nau8821:  component to register the codec private data with
> + * @timeout: how long in jiffies to wait before failure or zero to wait
> + * until release

So, this driver looks pretty good apart from this semaphore usage which
is both not very clearly documented centrally (in terms of the purpose
and what it's protecting) and just uses semaphores which is generally
unusual and worrying, there's a push to try to eliminate semaphores from
the kernel and replace them with clearer and more appropriate locking
primitives.

My understanding is that the main goal is to avoid any CODEC operations
running while jack detection runs during resume.  I think this could be
done more cleanly by having a completion in the component level resume
function (not the I2C level one) - the core will resume the card in a
thread without blocking the main resume thread used for the rest of the
system which as far as I can tell is what you're trying to avoid
problems with here.  set_bias_level() or a DAPM _PRE widget might also
serve.  You could possibly even just do the resume and redetection from
the CODEC level resume callback and get the effect you're looking for.

It's possible I've misunderstood exactly what the goal is here so that
might not work, if you could clarify what's going on that might help.
It might be easiest to split this into two patches, one for the main
driver then another adding jack detection (and anything else affected by
the semaphore) - that way the main driver can be reviewed and hopefully
merged quickly while we figure out what's going on with the jack
detection bit.

Otherwise this looks good, a few small issues but nothing major:

> +static int nau8821_digital_mute(struct snd_soc_dai *dai, int mute, int direction)
> +{
> +	struct snd_soc_component *component = dai->component;
> +	struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component);
> +	unsigned int val;
> +
> +	val = mute ? NAU8821_DAC_SOFT_MUTE : 0;

Please use normal conditional statements to improve legibility.

> +static int nau8821_component_probe(struct snd_soc_component *component)
> +{
> +	struct nau8821 *nau8821 = snd_soc_component_get_drvdata(component);
> +	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
> +
> +	nau8821->dapm = dapm;
> +
> +	snd_soc_dapm_sync(nau8821->dapm);

The core should sync everything at the end of card bringup, no need to
do that in the driver.

> +		"nuvoton,jkdet-enable");
> +	nau8821->jkdet_pull_enable = device_property_read_bool(dev,
> +		"nuvoton,jkdet-pull-enable");
> +	nau8821->jkdet_pull_up = device_property_read_bool(dev,
> +		"nuvoton,jkdet-pull-up");
> +	ret = device_property_read_u32(dev, "nuvoton,jkdet-polarity",
> +		&nau8821->jkdet_polarity);

These properties need a DT binding document.

> +static void nau8821_init_regs(struct nau8821 *nau8821)
> +{
> +	struct regmap *regmap = nau8821->regmap;

> +	/* Disable Boost Driver, Automatic Short circuit protection enable */
> +	regmap_update_bits(regmap, NAU8821_R76_BOOST,
> +		NAU8821_PRECHARGE_DIS | NAU8821_HP_BOOST_DIS |

I'd expect the boost driver disable and some of the other stuff like DAC
disable to be done automatically by DAPM.

> +	/**/
> +	regmap_update_bits(regmap, NAU8821_R13_DMIC_CTRL,

Missing comment?

> +	/* Pull up IRQ pin */
> +	regmap_update_bits(regmap, NAU8821_R0F_INTERRUPT_MASK,
> +		NAU8821_IRQ_PIN_PULL_UP | NAU8821_IRQ_PIN_PULL_EN |
> +		NAU8821_IRQ_OUTPUT_EN, NAU8821_IRQ_PIN_PULL_UP |
> +		NAU8821_IRQ_PIN_PULL_EN | NAU8821_IRQ_OUTPUT_EN);

Should this be a device property?

> +	ret = devm_snd_soc_register_component(&i2c->dev, &nau8821_component_driver,
> +		&nau8821_dai, 1);
> +	pr_err("%s exit ret:%d\n", __func__, ret);
> +	return ret;

Remove the pr_err(), guess it's just leftover debugging.

> +static int nau8821_i2c_remove(struct i2c_client *client)
> +{
> +	return 0;
> +}

This is empty so can be removed.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://mailman.alsa-project.org/pipermail/alsa-devel/attachments/20210716/bbd7a431/attachment.sig>


More information about the Alsa-devel mailing list