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);
时间: 2024-10-31 06:16:00