如上,应用部分通过setMasterVolume,最终调用到AF的setMasterVolume,
status_t AudioFlinger::setMasterVolume(float value) { for (size_t i = 0; i < mAudioHwDevs.size(); i++) { AutoMutex lock(mHardwareLock); AudioHwDevice *dev = mAudioHwDevs.valueAt(i);
mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME; if (dev->canSetMasterVolume()) { dev->hwDevice()->set_master_volume(dev->hwDevice(), value); } mHardwareStatus = AUDIO_HW_IDLE; }
for (size_t i = 0; i < mPlaybackThreads.size(); i++) { if (mPlaybackThreads.valueAt(i)->isDuplicating()) { continue; } mPlaybackThreads.valueAt(i)->setMasterVolume(value); }
return NO_ERROR; }
|
如我们以前分析,会走到audio_hw.c,可惜这里是个stub函数,没有真正实现,
static int adev_set_master_volume(struct audio_hw_device *dev __unused, float volume __unused) { return -ENOSYS; }
|
setMasterVolume如果实现,在现有平台,最终会走到\kernel\msm-4.4\sound\ppc\tumbler.c里面,
static int tumbler_set_master_volume(struct pmac_tumbler *mix) { unsigned char block[6]; unsigned int left_vol, right_vol; if (! mix->master_switch[0]) left_vol = 0; else { left_vol = mix->master_vol[0]; if (left_vol >= ARRAY_SIZE(master_volume_table)) left_vol = ARRAY_SIZE(master_volume_table) - 1; left_vol = master_volume_table[left_vol]; } if (! mix->master_switch[1]) right_vol = 0; else { right_vol = mix->master_vol[1]; if (right_vol >= ARRAY_SIZE(master_volume_table)) right_vol = ARRAY_SIZE(master_volume_table) - 1; right_vol = master_volume_table[right_vol]; } … if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_VOL, 6, block) < 0) { snd_printk(KERN_ERR "failed to set volume \n"); return -EINVAL; } DBG("(I) succeeded to set volume (%u, %u)\n", left_vol, right_vol); return 0; }
|
这个文件是TAS3001c的驱动接口文件,将用户设置的参数数据通过I2C写入这个数字音频设备的系统控制单元,来控制音量的增益。
这款数字音频设备的功能块图如下,
对应于代码中的master_volume_table,
也就是其增益表,我们可以在datasheet找到相应的参数表,
另外,data manual还给出了该器件的一个典型使用场景,