All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Brown <broonie@kernel.org>
To: Oder Chiou <oder_chiou@realtek.com>
Cc: bardliao@realtek.com, alsa-devel@alsa-project.org,
	lgirdwood@gmail.com, flove@realtek.com
Subject: Re: [PATCH] ASoC: rt5645: Add codec driver
Date: Mon, 14 Apr 2014 21:28:37 +0100	[thread overview]
Message-ID: <20140414202837.GA25182@sirena.org.uk> (raw)
In-Reply-To: <1397212459-26495-1-git-send-email-oder_chiou@realtek.com>


[-- Attachment #1.1: Type: text/plain, Size: 5437 bytes --]

On Fri, Apr 11, 2014 at 06:34:19PM +0800, Oder Chiou wrote:
> This patch adds the Realtek ALC5645 codec driver. It is the base
> version that because the jack detect function is not implemented to
> it, the headphone and AMIC1 are not workable. We will fill up the
> further functions later.

This looks pretty good, a few things below but none of them too big.

> +static bool rt5645_readable_register(struct device *dev, unsigned int reg)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(rt5645_ranges); i++)
> +		if ((reg >= rt5645_ranges[i].window_start &&
> +		     reg <= rt5645_ranges[i].window_start +
> +		     rt5645_ranges[i].window_len) ||
> +		    (reg >= rt5645_ranges[i].range_min &&
> +		     reg <= rt5645_ranges[i].range_max))
> +			return true;

Please include some braces in these loops for legibility.

> +static int rt5645_set_dmic1_event(struct snd_soc_dapm_widget *w,
> +	struct snd_kcontrol *kcontrol, int event)
> +{
> +	struct snd_soc_codec *codec = w->codec;
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		snd_soc_update_bits(codec, RT5645_GPIO_CTRL1,
> +			RT5645_GP2_PIN_MASK, RT5645_GP2_PIN_DMIC1_SCL);
> +		snd_soc_update_bits(codec, RT5645_DMIC1, RT5645_DMIC_1_DP_MASK,
> +			RT5645_DMIC_1_DP_IN2N);
> +		break;

For rt5640 we've got this configued by platform data - why not do the
same here?  In general I'm seeing some similarities again, though I
didn't check to see if the same driver can be used yet.  Is that the
case?

> +static const struct snd_kcontrol_new hp_r_vol_control =
> +	SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_HP_VOL,
> +
> +		RT5645_R_MUTE_SFT, 1, 1);
> +static void hp_amp_power(struct snd_soc_codec *codec, int on)

Coding style, your blank line is in the wrong place.

> +static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
> +	struct snd_kcontrol *kcontrol, int event)
> +{
> +	struct snd_soc_codec *codec = w->codec;
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_POST_PMU:
> +		rt5645_pmu_depop(codec);
> +		break;
> +
> +	case SND_SOC_DAPM_PRE_PMD:
> +		rt5645_pmd_depop(codec);
> +		break;

May as well just inline the power up/down sequences?

> +	case SND_SOC_DAPM_POST_PMU:
> +		regmap_write(rt5645->regmap, RT5645_PR_BASE + 0x1c, 0xfd20);
> +		regmap_write(rt5645->regmap, RT5645_PR_BASE + 0x20, 0x611f);
> +		regmap_write(rt5645->regmap, RT5645_PR_BASE + 0x21, 0x4040);
> +		regmap_write(rt5645->regmap, RT5645_PR_BASE + 0x23, 0x0004);
> +		snd_soc_update_bits(codec, RT5645_PWR_DIG1,
> +			RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |

Either use snd_soc_ or regmap_ - either is fine but be consistent.

> +			RT5645_PWR_CLS_D_L,
> +			RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
> +			RT5645_PWR_CLS_D_L);
> +		break;
> +
> +	case SND_SOC_DAPM_PRE_PMD:
> +		snd_soc_update_bits(codec, RT5645_PWR_DIG1,
> +			RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
> +			RT5645_PWR_CLS_D_L, 0);

It's a bit odd that the first bank of writes done with regmap_write()
isn't undone here, can it be done once on init?

> +static int rt5645_pdm1_l_event(struct snd_soc_dapm_widget *w,
> +	struct snd_kcontrol *kcontrol, int event)
> +{
> +	struct snd_soc_codec *codec = w->codec;
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_POST_PMU:
> +		snd_soc_update_bits(codec, RT5645_PDM_OUT_CTRL,
> +			RT5645_M_PDM1_L, 0);
> +		break;

Why are these done by an event - I'd expect this to be done using the
normal DAPM register update support?

> +	bclk_ms = frame_size > 32 ? 1 : 0;

bclk_ms = frame_size > 32.

> +static int rt5645_set_bias_level(struct snd_soc_codec *codec,
> +			enum snd_soc_bias_level level)
> +{
> +	switch (level) {
> +	case SND_SOC_BIAS_STANDBY:
> +		if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
> +			snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
> +				RT5645_PWR_VREF1 | RT5645_PWR_MB |
> +				RT5645_PWR_BG | RT5645_PWR_VREF2,
> +				RT5645_PWR_VREF1 | RT5645_PWR_MB |
> +				RT5645_PWR_BG | RT5645_PWR_VREF2);
> +			mdelay(10);
> +			snd_soc_update_bits(codec, RT5645_PWR_ANLG1,
> +				RT5645_PWR_FV1 | RT5645_PWR_FV2,
> +				RT5645_PWR_FV1 | RT5645_PWR_FV2);
> +			snd_soc_update_bits(codec, RT5645_GEN_CTRL1,
> +				RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL);
> +		}
> +		break;

Since the device can power up and down very quickly it should make sense
to set idle_bias_off for a power saving when idle.

> +#ifdef CONFIG_PM
> +static int rt5645_suspend(struct snd_soc_codec *codec)
> +{
> +	rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF);
> +	return 0;
> +}
> +
> +static int rt5645_resume(struct snd_soc_codec *codec)
> +{
> +	return 0;
> +}
> +#else
> +#define rt5645_suspend NULL
> +#define rt5645_resume NULL
> +#endif

If you use idle_bias_off you can remove this.

> +#if defined(CONFIG_OF)
> +static const struct of_device_id rt5645_of_match[] = {
> +	{ .compatible = "realtek,rt5645", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, rt5645_of_match);
> +#endif

We need device tree binding documentation for any device with DT
bindings.

> +static int rt5645_i2c_remove(struct i2c_client *i2c)
> +{
> +	snd_soc_unregister_codec(&i2c->dev);
> +	kfree(i2c_get_clientdata(i2c));
> +	return 0;
> +}

You used devm_kzalloc(), no need to free.

> +void rt5645_i2c_shutdown(struct i2c_client *client)
> +{
> +	struct rt5645_priv *rt5645 = i2c_get_clientdata(client);
> +	struct snd_soc_codec *codec = rt5645->codec;
> +
> +	if (codec != NULL)
> +		rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF);
> +}

The ASoC framework will do this for you.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



  reply	other threads:[~2014-04-14 20:28 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-11 10:34 [PATCH] ASoC: rt5645: Add codec driver Oder Chiou
2014-04-14 20:28 ` Mark Brown [this message]
2014-04-22  1:04   ` Oder
2014-04-22  1:10   ` Oder
2014-04-22 10:53     ` 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=20140414202837.GA25182@sirena.org.uk \
    --to=broonie@kernel.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=bardliao@realtek.com \
    --cc=flove@realtek.com \
    --cc=lgirdwood@gmail.com \
    --cc=oder_chiou@realtek.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 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.