Android - Audio - MT67平台 - hac器件bring up

948 阅读6分钟

1.audio_device.xml中添加hac path。

device/mediatek/mt6765/audio_device.xml中添加HAC_PA的控件声明和path操作。


<!--begin add by fuhua for task 8834760 on 2020-02-19-->

<path name="hac_output" value="turnon">

<kctl name="Hac_Switch" value="On" />

</path>

<path name="hac_output" value="turnoff">

<kctl name="Hac_Switch" value="Off" />

</path>

<!--end add by fuhua for task 8834760 on 2020-02-19-->

<!--receiver output-->

<path name="receiver_output" value="turnon">

<kctl name="Voice_Amp_Switch" value="On" />

<kctl name="Hac_Switch" value="On" />

</path>

<path name="receiver_output" value="turnoff">

<kctl name="Voice_Amp_Switch" value="Off" />

<kctl name="Hac_Switch" value="Off" />

</path>


由于只是兼容,为了更方便测试,我直接就在BSP版本中打开Receiver的时候打开HAC了,这样方便测试。

2.在kernel当中注册SOC_ENUM_EXT而不是SOC_ENUM_SINGLE_EXT,然后添加实际引脚操作

MTK定制控件的文件路径是kernel-4.9\sound\soc\mediatek\codec\mt6357\mtk-soc-codec-6357.c,具体代码位置这个主要和平台定制有关,Qcom就是在vendor下的。


/* Begin modify by fuhua.wang for task 8834760 on 2020-02-19 */

static int Hac_Switch_Get(struct snd_kcontrol *kcontrol,

struct snd_ctl_elem_value *ucontrol)

{

/* pr_debug("%s()\n", __func__); */

pr_err("fuhua--check HAC function!! in Hac_Switch_Get\n");

ucontrol->value.integer.value[0] =

mCodec_data->mAudio_Ana_DevicePower

[AUDIO_ANALOG_DEVICE_OUT_EXTSPKAMP];

return 0;

}

static int Hac_Switch_Set(struct snd_kcontrol *kcontrol,

struct snd_ctl_elem_value *ucontrol)

{

pr_err("%s() :fuhua -- check gain = %ld\n ", __func__,

ucontrol->value.integer.value[0]);

if (ucontrol->value.integer.value[0]) {

AudDrv_GPIO_HAC_PA_Select(true);

} else {

AudDrv_GPIO_HAC_PA_Select(false);

}

return 0;

}

/* End modify by fuhua.wang for task 8834760 on 2020-02-19 */

......

/* Begin modify by fuhua.wang for task 8834760 on 2020-02-20*/

static const char * const hac_switch[] = { "Off", "On"};

/* End modify by fuhua.wang for task 8834760 on 2020-02-20*/

......

static const struct soc_enum Audio_DL_Enum[] = {

......

/* Begin modify by fuhua.wang for task 8834760 on 2020-02-19*/

SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(hac_switch), hac_switch),

/* End modify by fuhua.wang for task 8834760 on 2020-02-19 */

};

static const struct snd_kcontrol_new mt6357_snd_controls[] = {

......

/* Begin modify by fuhua.wang for task 8834760 on 2020-02-19*/

SOC_ENUM_EXT("Hac_Switch", Audio_DL_Enum[15],

Hac_Switch_Get,

Hac_Switch_Set),

/* End modify by fuhua.wang for task 8834760 on 2020-02-19 */

...


添加引脚操作的时候,需要注意最好是在dtsi或者mtk提供的dws中添加,然后再在代码中进行操作,保证代码干净整洁易懂易维护。

kernel-4.9\arch\arm64\boot\dts\mediatek\k62v1_64_bsp.dts中添加引脚操作


/* AUDIO GPIO standardization */

&audgpio {

......

/* Begin modify by fuhua.wang for task 8834760 on 2020-02-19*/

pinctrl-10 = <&hac_pins_on>;

pinctrl-11 = <&hac_pins_off>;

/* End modify by fuhua.wang for task 8834760 on 2020-02-19 */

......

/* Begin modify by fuhua.wang for task 8834760 on 2020-02-19*/

hac_pins_on: hac_pins_on {

pins_cmd_dat {

pinmux = <PINMUX_GPIO154__FUNC_GPIO154>;

slew-rate=<1>;

output-high;

};

};

hac_pins_off: hac_pins_off {

pins_cmd_dat {

pinmux = <PINMUX_GPIO154__FUNC_GPIO154>;

slew-rate=<1>;

output-low;

};

};

/* End modify by fuhua.wang for task 8834760 on 2020-02-19 */


还有mtk特有的dws文件中修改初始引脚电平,不然会出现开机hac器件就开始工作的情况,会有功耗的损耗。


<gpio154>

<eint_mode>false</eint_mode>

<def_mode>0</def_mode>

<inpull_en>false</inpull_en>

<inpull_selhigh>false</inpull_selhigh>

<def_dir>OUT</def_dir>

<out_high>false</out_high>

<smt>false</smt>

<ies>true</ies>

</gpio154>


然后在实现引脚操作的位置添加具体操作逻辑,kernel-4.9\sound\soc\mediatek\common_int\mtk-auddrv-gpio.c


/* Begin modify by fuhua.wang for task 8834760 on 2020-02-19 */

GPIO_HAC_PA_HIGH,

GPIO_HAC_PA_LOW,

/* End modify by fuhua.wang for task 8834760 on 2020-02-19 */

......

/* Begin modify by fuhua.wang for task 8834760 on 2020-02-19 */

[GPIO_HAC_PA_HIGH] = {"hac_pins_on", false, NULL},

[GPIO_HAC_PA_LOW] = {"hac_pins_off", false, NULL},

/* End modify by fuhua.wang for task 8834760 on 2020-02-19 */

......

/* Begin modify by fuhua.wang for task 8834760 on 2020-02-19 */

int AudDrv_GPIO_HAC_PA_Select(int bEnable)

{

int retval = 0;

#if MT6755_PIN

mutex_lock(&gpio_request_mutex);

if (bEnable == 1) {

pr_err("fuhua--check in %s hac enable!!!\n",__func__);

if (aud_gpios[GPIO_HAC_PA_HIGH].gpio_prepare) {

retval = pinctrl_select_state(

pinctrlaud,

aud_gpios[GPIO_HAC_PA_LOW].gpioctrl);

if (retval)

pr_info("could not set aud_gpios[GPIO_HAC_PA_LOW] pins\n");

udelay(2);

retval = pinctrl_select_state(

pinctrlaud,

aud_gpios[GPIO_HAC_PA_HIGH].gpioctrl);

if (retval)

pr_info("could not set aud_gpios[GPIO_HAC_PA_HIGH] pins\n");

udelay(2);

}

} else {

pr_err("fuhua--check in %s hac disenable!!!\n",__func__);

if (aud_gpios[GPIO_HAC_PA_LOW].gpio_prepare) {

retval = pinctrl_select_state(

pinctrlaud,

aud_gpios[GPIO_HAC_PA_LOW].gpioctrl);

if (retval)

pr_info("could not set aud_gpios[GPIO_HAC_PA_LOW] pins\n");

}

}

mutex_unlock(&gpio_request_mutex);

#endif

return retval;

}

/* End modify by fuhua.wang for task 8834760 on 2020-02-19 */


然后在.h文件中进行定义即可在逻辑代码中用到了(kernel-4.9\sound\soc\mediatek\common_int\mtk-auddrv-gpio.h)


/* Begin modify by fuhua.wang for task 8834760 on 2020-02-19 */

int AudDrv_GPIO_HAC_PA_Select(int bEnable);

/* End modify by fuhua.wang for task 8834760 on 2020-02-19 */


3.HAL层中操作

MTK的HAL层中的操作是以设备为重心的,看了代码之后会有很深刻的体会。

针对HAC的修改我这边主要是在vendor\mediatek\proprietary\hardware\audio\common\V3\aud_drv\AudioALSAHardwareResourceManager.cpp进行的。


//add by fuhua

#include "SpeechEnhancementController.h"

......

status_t AudioALSAHardwareResourceManager::OpenReceiverPath(const uint32_t SampleRate __unused) {

String8 value_str;

if (IsAudioSupportFeature(AUDIO_SUPPORT_2IN1_SPEAKER)) {

mDeviceConfigManager->ApplyDeviceTurnonSequenceByName(AUDIO_DEVICE_2IN1_SPEAKER);

} else {

mDeviceConfigManager->ApplyDeviceTurnonSequenceByName(AUDIO_DEVICE_RECEIVER);

}

//debug by fuhua

bool bEnable = SpeechEnhancementController::GetInstance()->GetHACOn();

ALOGE("fuhua---check --- OpenReceiverPath:HACsetting = %d",bEnable);

if(bEnable == true)

{mDeviceConfigManager->ApplyDeviceTurnonSequenceByName(AUDIO_DEVICE_HAC_SWITCH);}

else

{;}

......

status_t AudioALSAHardwareResourceManager::CloseReceiverPath() {

......

//debug by fuhua

bool bEnable = SpeechEnhancementController::GetInstance()->GetHACOn();

ALOGE("fuhua---check --- CloseReceiverPath:HACsetting = %d",bEnable);

if(bEnable == false)

{mDeviceConfigManager->ApplyDeviceTurnoffSequenceByName(AUDIO_DEVICE_HAC_SWITCH);}

else

{;}


然后就是在vendor\mediatek\proprietary\hardware\audio\common\V3\include\AudioALSADeviceConfigManager.h中定义AUDIO_DEVICE_HAC_SWITCH


/* Begin modify by fuhua.wang for task 7598168 for audio-bring-up*/

#define AUDIO_DEVICE_SPEAKER_VOICE "ext_speaker_voice_output"

/* End modify by fuhua.wang for task 7598168 for audio-bring-up*/

#define AUDIO_DEVICE_2IN1_SPEAKER "two_in_one_speaker_output"

#define AUDIO_DEVICE_RECEIVER "receiver_output"

/* Begin modify by fuhua.wang for task 8834760 on 2020-02-19*/

#define AUDIO_DEVICE_HAC_SWITCH "hac_output"

/* End modify by fuhua.wang for task 8834760 on 2020-02-19*/


通过ApplyDeviceTurnoffSequenceByName接口就可以调用path了。而Qcom是直接用的tinymix接口,并不像MTK这样封装了一层又一层,除非MTK想的是这套软件还有其他业务。 相对Qcom而言,MTK在定制这一方面做了很多工作,自己需要写的代码量很少,但是看代码,理逻辑,debug的时间又多做起来又繁琐,虽然Qcom需要写的代码量大,但是算上debug和定制的时间,基本持平,自由度还高一点,只要不怕难,我觉得这样还好一些。

4.MMITest软件中添加HAC测试的思路

理论上我们能在frameworks/av/media/libaudioclient/ 找到 AudioSystem.cpp 67 static const char* keyHACSetting = "HACSetting";

进一步寻找,可以发现packages/services/Telephony/src/com/android/phone/PhoneGlobals.java


390 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

391 audioManager.setParameter(SettingsConstants.HAC_KEY,

392 hac == SettingsConstants.HAC_ENABLED

393 ? SettingsConstants.HAC_VAL_ON : SettingsConstants.HAC_VAL_OFF);


所以可以尝试在MMI中能否使用该接口,理论上应该是可以的。因为MMITest里面也有这样的代码:


HeadsetTest.java:253: mAudioManager.setParameters("SET_LOOPBACK_TYPE=2,2");

HeadsetTest.java:257: mAudioManager.setParameters("SET_LOOPBACK_TYPE=0,0");


结语

1. 那么至此,基于MTK平台的hac器件bring up就告一段落了,除了MMITest没有验证之外,剩下的可能就是一些维护工作了。

2. 不知道这次的项目上hac器件噪声会不会严重,之前Qcom项目上由于布局的原因,加上屏幕的干扰,实际上是有干扰的,因为背光的信号频率很高。