[alsa-devel] [PATCH v3] ASoC: Add Freescale SGTL5000 codec support
Arnaud Patard (Rtp)
arnaud.patard at rtp-net.org
Thu Feb 17 09:52:52 CET 2011
<zhaoming.zeng at freescale.com> writes:
Hi,
> From: Zeng Zhaoming <zhaoming.zeng at freescale.com>
>
> Add Freescale SGTL5000 codec support
>
> Signed-off-by: Zeng Zhaoming <zhaoming.zeng at freescale.com>
> ---
> changes since v2:
> 1. clean up register default values
> 2. rewrite codec power up code, add sgtl5000_set_power_regs()
> 3. rewrite codec clock configure code sgtl5000_set_clock()
> 4. reimplement PM hooks, restore register by particular order.
> 5. clean up dapm code, remove dac and adc event hooks.
> 6. clean up codec private structure, remove unnecessary fields.
> 7. add comments for uncommon code.
>
> Thanks for Mark's review.
[...]
> +/*
> + * custom put function for PCM playback volume
> + * PCM volume with 0.5017 dB steps from 0 to -90 dB
> + * 0x3B and less = Reserved
> + * 0x3C = 0 dB
> + * 0x3D = -0.5 dB
> + * 0xF0 = -90 dB
> + * 0xFC and greater = Muted
> + */
> +static int dac_put_volsw(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
> + int reg, l, r;
> +
> + l = ucontrol->value.integer.value[0];
> + r = ucontrol->value.integer.value[1];
> +
> + l = l < 0 ? 0 : l;
> + l = l > 0xfc - 0x3c ? 0xfc - 0x3c : l;
> + r = r < 0 ? 0 : r;
> + r = r > 0xfc - 0x3c ? 0xfc - 0x3c : r;
> + l = 0xfc - l;
> + r = 0xfc - r;
> +
> + reg = l << SGTL5000_DAC_VOL_LEFT_SHIFT |
> + r << SGTL5000_DAC_VOL_RIGHT_SHIFT;
> +
> + snd_soc_update_bits_locked(codec, SGTL5000_CHIP_DAC_VOL, reg, reg);
Why are you using update_bits_locked and not snd_soc_write ?
Here snd_soc_update_bits_locked is just good at making the PCM playback
mixer acting weird (I even got to a point that with a 0 value in the
mixer, I was unable to raise the volume). snd_soc_write just works.
[...]
> +
> +static int sgtl5000_probe(struct snd_soc_codec *codec)
> +{
> + struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec);
> + u16 reg;
> + int ret;
> + int rev;
> + int i;
> +
> + /* setup i2c data ops */
> + ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
> + if (ret < 0) {
> + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
> + return ret;
> + }
> +
> + /* read chip information */
> + reg = snd_soc_read(codec, SGTL5000_CHIP_ID);
I've a problem with doing that here. You do assume that the regulators
are enabled at this point which is not always the case. This results on
a timeout on i2c and then reg contains 0. Please enable regultors firsts
And no, I don't see having the regulators for things like vddio set to
"always on" in the machine file as a good idea. If the driver is not
loaded, having the codec off is good for power consumption.
Arnaud
More information about the Alsa-devel
mailing list