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 --]
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox