[alsa-devel] [PATCH 1/3] ASoC: add 88pm860x codec driver
Haojian Zhuang
haojian.zhuang at gmail.com
Wed Aug 18 10:33:19 EDT 2010
On Wed, Aug 18, 2010 at 10:19 PM, Mark Brown
<broonie at opensource.wolfsonmicro.com> wrote:
> On Wed, Aug 18, 2010 at 09:49:26PM +0800, Haojian Zhuang wrote:
>
>> + if (dac) {
>> + /* automute is set before operating DAC. Anti-pop */
>> + mutex_lock(&pm860x->mutex);
>> + pm860x->automute = 1;
>> + dac |= MODULATOR;
>> + /* mute */
>> + snd_soc_update_bits(codec, PM860X_DAC_OFFSET,
>> + DAC_MUTE, DAC_MUTE);
>> + snd_soc_update_bits(codec, PM860X_EAR_CTRL_2,
>> + RSYNC_CHANGE, RSYNC_CHANGE);
>> + mutex_unlock(&pm860x->mutex);
>> + /* update dac */
>> + snd_soc_update_bits(codec, PM860X_DAC_EN_2,
>> + dac, dac);
>> + }
>
>
> I still can't follow what this automute variable is supposed to be
> doing. In both the PMU and the PMD cases you set automute, and the fact
> that you forcibly clear it when you apply the change means that it
> doesn't look like it's doing anything I'd recognise as automute,
> suggesting that the variable is misnamed. It's very difficult to follow
> what all this is supposed to be doing.
>
Mute while DAC is enabled and PGA is updated. It's the purpose of
anti-pop by silicon.
> As I said last time what I'd expect to see is a user visible mute
> control which sets a variable in the driver which is then updated in the
> chip only while the DAC is powered. The other option is to tie the
> control to the DAC power, in which case things should be handleable in
> the widget event without the variable.
>
Why should I move the work to invoking amixer by user? Why shouldn't
it be taken by driver automatically?
>> +static int pm860x_digital_mute(struct snd_soc_dai *codec_dai, int mute)
>> +{
>> + struct snd_soc_codec *codec = codec_dai->codec;
>> + int data = 0;
>> +
>> + if (mute)
>> + data = DAC_MUTE;
>> + snd_soc_update_bits(codec, PM860X_DAC_OFFSET, DAC_MUTE, data);
>
> This isn't joined up at all with the automute code above...
>
>> + /* set master/slave audio interface */
>> + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
>> + case SND_SOC_DAIFMT_CBM_CFM:
>> + case SND_SOC_DAIFMT_CBM_CFS:
>> + if (pm860x->dir == PM860X_CLK_DIR_OUT) {
>> + inf |= PCM_INF2_MASTER;
>> + ret = 0;
>
> This is still setting the same register value for two different DAI
> formats. You need to fix this, and in the other set_fmt() function.
>
These two registers are EXACTLY same. Why do I need to define two same
bit macro?
> You're also missing a default: case.
>
Please check the code. If it's default case, it'll return -EINVAL. I
didn't miss it.
>> + if ((pm860x->det.hs_shrt & SND_JACK_BTN_0)
>> + && (shrt & (SHORT_HS1 | SHORT_HS2)))
>> + report |= SND_JACK_BTN_0;
>> +
>> + if ((pm860x->det.hook_det & SND_JACK_BTN_1)
>> + && (status & HOOK_STATUS))
>> + report |= SND_JACK_BTN_1;
>> +
>> + if ((pm860x->det.lo_shrt & SND_JACK_BTN_2)
>> + && (shrt & (SHORT_LO1 | SHORT_LO2)))
>> + report |= SND_JACK_BTN_2;
>
> You should ideally allow the user to override these via platform data if
> the buttons have specific functions.
>
OK.
> One other thing you should do is split the jack configuration for
> headphone and microphone - a system may have two physical jacks, one for
> each, so you should allow the user to configure the detection onto
> separate jacks if they want to.
>
Up to now, I can't split it to two different jacks. Since there's some
issue on mic detection.
More information about the linux-arm-kernel
mailing list