http://blog.csdn.net/morixinguan/article/details/56514356
之前写过一篇文章,是对alc5623.c codec部分进行了大致框架的分析,现在要解决一些实际问题,关于上层的代码我就不公布了,只公布在驱动的代码:
在手册中,我们看到一个这样的寄存器设置。
先来看看说明文档,主要是做主音量的输出。
下面就是详细的如何配置0x0C的寄存器
我遇到的问题是,到了上层应用,无法通过按键调节主音量,并会提示:
can't find simple control"Master",0
如何解决?
在kcontrol中添加一个Master,用它来做主音量控制。
static const struct snd_kcontrol_newalc5621_vol_snd_controls[] = {
SOC_DOUBLE_TLV("MasterPlayback Volume",
ALC5623_STEREO_DAC_VOL,8, 0, 31, 1, vol_tlv),
SOC_DOUBLE("MasterPlayback Switch",
ALC5623_STEREO_DAC_VOL,15, 7, 1, 1),
…………………
};
SOC_DOUBLE_TLV在这个宏中已经配置了info和put函数,意思就是设置音量还有获取音量。
//set函数设置音量
nt snd_soc_info_volsw(struct snd_kcontrol*kcontrol,
structsnd_ctl_elem_info *uinfo)
{
structsoc_mixer_control *mc =
(structsoc_mixer_control *)kcontrol->private_value;
intplatform_max;
if(!mc->platform_max)
mc->platform_max= mc->max;
platform_max= mc->platform_max;
if(platform_max == 1 && !strstr(kcontrol->id.name, "Volume"))
uinfo->type= SNDRV_CTL_ELEM_TYPE_BOOLEAN;
else
uinfo->type= SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count= snd_soc_volsw_is_stereo(mc) ? 2 : 1;
uinfo->value.integer.min= 0;
uinfo->value.integer.max= platform_max;
return0;
}
//put函数获取音量
int snd_soc_put_volsw(struct snd_kcontrol*kcontrol,
structsnd_ctl_elem_value *ucontrol)
{
structsoc_mixer_control *mc =
(structsoc_mixer_control *)kcontrol->private_value;
structsnd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
unsignedint reg = mc->reg;
unsignedint reg2 = mc->rreg;
unsignedint shift = mc->shift;
unsignedint rshift = mc->rshift;
intmax = mc->max;
unsignedint mask = (1 << fls(max)) - 1;
unsignedint invert = mc->invert;
interr;
booltype_2r = 0;
unsignedint val2 = 0;
unsignedint val, val_mask;
val= (ucontrol->value.integer.value[0] & mask);
if(invert)
val= max - val;
val_mask= mask << shift;
val= val << shift;
if(snd_soc_volsw_is_stereo(mc)) {
val2= (ucontrol->value.integer.value[1] & mask);
if(invert)
val2= max - val2;
if(reg == reg2) {
val_mask|= mask << rshift;
val|= val2 << rshift;
}else {
val2= val2 << shift;
type_2r= 1;
}
}
err= snd_soc_update_bits_locked(codec, reg, val_mask, val);
if(err < 0)
returnerr;
if(type_2r)
err= snd_soc_update_bits_locked(codec, reg2, val_mask, val2);
returnerr;
}
那么设置完后编译通过后下到板子里就可以正常驱动了。
还有一个问题,当耳机插入时,调节音量,耳机在放,喇叭也在放,怎么解决?
在耳机插入时:
只要将喇叭关掉,将耳机开启就可以了。
下面的这两步操作最为关键,当耳机插入时,关闭喇叭,将音源更新到耳机里。
snd_soc_update_bits(codec, 0x04, 0x8080,0x8080);
snd_soc_update_bits(codec, 0x02, 0x8080,0x0);