Android - Audio - Qcom平台 - hac器件bring up
?
- 背景
- 正文
- 助聽(tīng)器構(gòu)造
- 使用方式
- HAC部分硬件原理圖
- 硬件調(diào)試需求
- 軟件平臺(tái)及框架
- a:mixer_path.xml中添加hac path
- b:alsa用戶空間,tinyalsa中注冊(cè)HAC控件
- c:GPIO_HAC_EN
- d:添加acdb_id
- e:為MMITest添加測(cè)試項(xiàng)
- 結(jié)語(yǔ)
背景
公司的項(xiàng)目要求支持助聽(tīng)器(HAC器件,Hearing Aid Compatibility),以此正好再?gòu)?fù)習(xí)一下在android的框架下如何bring up一個(gè)類(lèi)似PA的器件。
正文
我們首先需要了解助聽(tīng)器的原理,使用方式(以此確定測(cè)試手段),硬件原理圖(以此確定軟件如何適配),硬件調(diào)試需求,軟件平臺(tái)以及框架(MTK和Qcom在底層有一些差別)。
既然已經(jīng)明確了步驟,那么就開(kāi)始一步一步來(lái);
(1)助聽(tīng)器構(gòu)造:
從百度百科來(lái)看,助聽(tīng)器有5個(gè)主要的構(gòu)造,麥克風(fēng),放大器,接收器,電源和外殼。
其中對(duì)我們這次開(kāi)發(fā)有用的就是接收器,因?yàn)閙ic用手機(jī)的mic就夠了。
(2)使用方式:
按照我拿到的助聽(tīng)器,上了電池之后默認(rèn)是放大聲音的模式,我理解的助聽(tīng)器基本上也是放大器的作用,但是HAC器件實(shí)際上還有一個(gè)功能,就是電圈耦合,按下助聽(tīng)器上的按鈕觸發(fā),從以往的功能定義來(lái)看在打電話的時(shí)候該功能才打開(kāi)(但是個(gè)人疑問(wèn)助聽(tīng)器不是應(yīng)該時(shí)時(shí)刻刻都幫助聽(tīng)障人士更清楚的聽(tīng)到聲音么,難道是怕耗電快?)。
知道了使用方式,我在測(cè)試效果的時(shí)候發(fā)現(xiàn)Receiver發(fā)出的聲音實(shí)際上會(huì)影響到功能判斷,所以我直接將Receiver器件和speaker器件給去掉了(去掉speaker主要是為了測(cè)試后面添加path的可行性。)
(3)HAC部分硬件原理圖:
| +-----------+ INP +-------------+ VON +----------+ | CDC_EAR_M | ~~~~~> | | ~~~~~> | HAC 線圈 | +-----------+ | | +----------+| | VOP ^| AW8155FCR | ~~~~~~~~~*| | +-----------+ INN | | | CDC_EAR_P | ~~~~~> | | +-----------+ +-------------+^} INP}+-------------+| GPIO_HAC_EN |+-------------+ |
從原理圖我們能明顯的看到有一個(gè)艾薇的放大器,通過(guò)對(duì)CDC_EAR通路的查詢(xún),發(fā)現(xiàn)接到了Receiver器件上,所以電信號(hào)的數(shù)據(jù)輸出可以理解為既給了Receiver,會(huì)給到hac部分。
(4)硬件調(diào)試需求:
和硬件同事進(jìn)行溝通,發(fā)現(xiàn)有如下需求
–1. 器件bring up。
–2. 單獨(dú)一條acdb id。
–3. dialer界面有設(shè)置HAC功能打開(kāi)的接口。
–4. MMITest里面能進(jìn)行測(cè)試。
(5)軟件平臺(tái)及框架:
根據(jù)需求,我們可以大致確定這需要從上到下一起打通,那么就需要像普通的PA那樣單獨(dú)配置一個(gè)path,而且還需要額外加一條acdb_id,以供調(diào)試。
然后就是和上層通信的接口,可以按照屬性值的方式來(lái),也可以按照其他方式,暫時(shí)先通過(guò)屬性值來(lái)比較方便。
MMITest當(dāng)中則需要通過(guò)path的開(kāi)關(guān)來(lái)控制,所以配置一個(gè)單獨(dú)的path是必須的。
根據(jù)以上的軟件需求,我將此次的軟件開(kāi)發(fā)分為如下步驟:
a : mixer_path.xml中添加hac path。
b : 在alsa用戶空間,tinyalsa中注冊(cè)HAC控件。
c : tinyalsa中操作mixer,達(dá)到想調(diào)用hac path的時(shí)候能操作GPIO_HAC_EN,數(shù)據(jù)信號(hào)則不在此處控制。
d : hal層添加一個(gè)RX 的 acdb_id,TX已經(jīng)確定是4,RX為31。
e : MMITest測(cè)試調(diào)用的audio_test.sh中添加 HAC PATH 的開(kāi)關(guān)。
a
在hardware/qcom/audio/configs/msm8937/mixer_path_mtp.xml中添加HAC_PA的控件聲明和path操作。
| <ctl name="EAR PA Boost" value="ENABLE" /> <!-- begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 --> <ctl name="HAC_PA" value="On" /> <ctl name="HAC_PA" value="Off" /> <!-- end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 --> <ctl name="MI2S_RX Channels" value="One" /> |
在需要打開(kāi)PA的場(chǎng)景中打開(kāi)PA,此處應(yīng)個(gè)人測(cè)試需求,在speaker的path中也打開(kāi)了HAC_PA。
| <path name="voice-call"><ctl name="PRI_MI2S_RX_Voice Mixer CSVoice" value="1" /><ctl name="Voice_Tx Mixer TERT_MI2S_TX_Voice" value="1" /><!-- begin mod by fuhua for task: 8668750 on 2019-12-03 task id:8668750 --><ctl name="HAC_PA" value="On" /><!-- end mod by fuhua for task: 8668750 on 2019-12-03 task id:8668750 --> </path> <path name="speaker"><ctl name="RX3 MIX1 INP1" value="RX1" /><ctl name="SPK" value="Switch" /><!-- begin mod by fuhua for task: 8668750 on 2019-12-03 task id:8668750 --><ctl name="HAC_PA" value="On" /><!-- end mod by fuhua for task: 8668750 on 2019-12-03 task id:8668750 --> </path> |
這個(gè)時(shí)候我們能在mixer.xml中看到配置了path,但是tinyalsa并沒(méi)有注冊(cè)HAC_PA這條path,在我的理解這個(gè)并不是針對(duì)注冊(cè)的接口。
至于為什么選擇的是 mixer_paths_mtp.xml ,這個(gè)可以查看/hardware/qcom/audio/hal/msm8916/platform.c對(duì)聲卡的判斷,然后選擇對(duì)應(yīng)的mixer_path.xml文件。
b
在alsa用戶空間,tinyalsa中注冊(cè)HAC控件。
注冊(cè)的時(shí)候需要用到alsa提供出來(lái)的接口SOC_ENUM_SINGLE_EXT,當(dāng)然也有其他的接口,比如SOC_DAPM_ENUM、SOC_SINGLE_TLV;這兩個(gè)分別是需要注冊(cè)到動(dòng)態(tài)音頻電源管理模塊,另外一個(gè)的注釋是“Convenience kcontrol builders”,主要用于定義那些有增益控制的控件,例如音量控制器,EQ均衡器等等。
我的代碼如下( 路徑:vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/msm-analog-cdc.c ):
| /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ static const char * const hac_pa_text[] = { "Off", "On"}; static const struct soc_enum hac_enum[] = { SOC_ENUM_SINGLE_EXT(2, hac_pa_text), }; /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */.../*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ SOC_ENUM_EXT("HAC_PA", hac_enum[0],hac_pa_gpio_get,hac_pa_gpio_set), /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ |
c
實(shí)際上這里已經(jīng)注冊(cè)好了HAC_PA了,只要申明一下set函數(shù)和get函數(shù),然后編譯就能用tinymix看到HAC_PA的path了,但顯然是不能工作的。
所以接下來(lái)就是定義hac_pa_gpio_get以及hac_pa_gpio_set,其中hac_pa_set需要額外在sdm660_cdc_priv結(jié)構(gòu)體中添加,
| /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ static int hac_pa_gpio_get(struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol) {struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);struct sdm660_cdc_priv *sdm660_cdc =snd_soc_codec_get_drvdata(codec);ucontrol->value.integer.value[0] =(sdm660_cdc->hac_pa_set ? 1 : 0);dev_err(codec->dev, "%s: fuhua sdm660_cdc->hac_pa_set = %d\n",__func__, sdm660_cdc->hac_pa_set);return 0; }static int hac_pa_gpio_set(struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol) {struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);struct sdm660_cdc_priv *sdm660_cdc =snd_soc_codec_get_drvdata(codec);dev_err(codec->dev, "%s: fuhua ucontrol->value.integer.value[0] = %ld\n",__func__, ucontrol->value.integer.value[0]);sdm660_cdc->hac_pa_set =(ucontrol->value.integer.value[0] ? true : false);if(sdm660_cdc->hac_pa_set){//msm_cdc_pinctrl_select_active_state(sdm660_cdc->hac_pa_gpio_p);//enable_hac_pa(codec,true);if (sdm660_cdc->codec_hac_pa_cb)sdm660_cdc->codec_hac_pa_cb(codec, 1);}else{//msm_cdc_pinctrl_select_sleep_state(sdm660_cdc->hac_pa_gpio_p);//enable_hac_pa(codec,false);if (sdm660_cdc->codec_hac_pa_cb)sdm660_cdc->codec_hac_pa_cb(codec, 0);}return 0; }/*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ |
其中的set函數(shù)會(huì)讀取HAC_PA的控件值,然后去調(diào)用sdm660_cdc->codec_hac_pa_cb函數(shù),而這個(gè)函數(shù)指針在另一個(gè)地方已經(jīng)賦值成了另一個(gè)函數(shù),如下sdm660_cdc->codec_hac_pa_cb = codec_hac_pa;:
| /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ void msm_anlg_cdc_hac_pa_cb(int (*codec_hac_pa)(struct snd_soc_codec *codec,int enable), struct snd_soc_codec *codec) {struct sdm660_cdc_priv *sdm660_cdc;if (!codec) {pr_err("%s: NULL codec pointer!\n", __func__);return;}sdm660_cdc = snd_soc_codec_get_drvdata(codec);dev_err(codec->dev, "%s: fuhua Enter\n", __func__);sdm660_cdc->codec_hac_pa_cb = codec_hac_pa; } EXPORT_SYMBOL(msm_anlg_cdc_hac_pa_cb); /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ |
這個(gè)msm_anlg_cdc_hac_pa_cb已經(jīng)在msm-analog-cdc.h中已經(jīng)聲明成extern。剛剛我們?cè)趕dm660_cdc這個(gè)目錄下完成了驅(qū)動(dòng)的注冊(cè),現(xiàn)在來(lái)到vendor/qcom/opensource/audio-kernel/asoc/msm8952.c繼續(xù)完成實(shí)現(xiàn),這些都是在alsa的用戶空間進(jìn)行操作的,也就是用了接口之后的部分。我們首先要在msm_audrx_init函數(shù)中調(diào)用msm_anlg_cdc_hac_pa_cb(enable_hac_pa, ana_cdc);,以注冊(cè)enable_hac_pa函數(shù)。
| static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) {struct snd_soc_codec *dig_cdc = rtd->codec_dais[DIG_CDC]->codec;struct snd_soc_codec *ana_cdc = rtd->codec_dais[ANA_CDC]->codec;...snd_soc_dapm_ignore_suspend(dapm, "EAR");snd_soc_dapm_ignore_suspend(dapm, "HEADPHONE");snd_soc_dapm_ignore_suspend(dapm, "SPK_OUT");.../*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */msm_anlg_cdc_hac_pa_cb(enable_hac_pa, ana_cdc);/*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ |
這個(gè)init函數(shù)中我們還能看到snd_soc_dapm_ignore_suspend函數(shù),這就是在哪里忽略path的地方。那么接下來(lái)就是具體實(shí)現(xiàn)enable_hac_pa ,代碼如下:
| /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ static int enable_hac_pa(struct snd_soc_codec *codec, int enable) {struct snd_soc_card *card = codec->component.card;struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);int ret = 0;int i = 0;int extamp_mode = 2; //ext pa default mode 2if (!gpio_is_valid(pdata->hac_pa_gpio)) {pr_err("%s: Invalid gpio: %d\n", __func__,pdata->hac_pa_gpio);return false;}pr_err("%s: %s fuhua HAC PA\n", __func__,enable ? "Enable" : "Disable");if (enable) {for( i=0 ; i<extamp_mode ; i++){ret = msm_cdc_pinctrl_select_sleep_state(pdata->hac_pa_gpio_p);if (ret) {pr_err("%s: gpio set cannot be de-sleeped %s\n ",__func__,"lo_spk_gpio");return ret;}udelay(2);ret = msm_cdc_pinctrl_select_active_state(pdata->hac_pa_gpio_p);if (ret) {pr_err("%s: gpio set cannot be de-activated %s\n",__func__, "lo_spk_gpio");return ret;}pr_err("%s: %s i=%d\n ",__func__,enable ? "Enable" : "Disable",i);}gpio_set_value_cansleep(pdata->hac_pa_gpio, enable);} else {gpio_set_value_cansleep(pdata->hac_pa_gpio, enable);pr_err("%s: %s\n ",__func__,enable ? "Enable" : "Disable");ret = msm_cdc_pinctrl_select_sleep_state(pdata->hac_pa_gpio_p);if (ret) {pr_err("%s: gpio set cannot be de-activated %s\n",__func__, "lo_spk_gpio");return ret;}}return 0; } /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ |
其中定義了pa的模式,extamp_mode,剩下的主要操作就是通過(guò)Qcom的接口開(kāi)關(guān)引腳了。
msm_cdc_pinctrl_select_active_state(pdata->hac_pa_gpio_p);
msm_cdc_pinctrl_select_sleep_state(pdata->hac_pa_gpio_p);
gpio_set_value_cansleep(pdata->hac_pa_gpio, enable);
但是控制的時(shí)候肯定不能直接指定端口嘛,這種太不便于管理了,我們是有管理的公司,要為后來(lái)的產(chǎn)品造福,不要寫(xiě)些爛代碼,雖然繁瑣。所以需要在probe的時(shí)候遍歷一遍:
| static int msm8952_asoc_machine_probe(struct platform_device *pdev) {struct snd_soc_card *card;struct msm_asoc_mach_data *pdata = NULL;const char *hs_micbias_type = "qcom,msm-hs-micbias-type";const char *ext_pa = "qcom,msm-ext-pa";const char *mclk = "qcom,msm-mclk-freq";const char *wsa = "asoc-wsa-codec-names";const char *wsa_prefix = "asoc-wsa-codec-prefixes";const char *type = NULL;const char *ext_pa_str = NULL;const char *wsa_str = NULL;const char *wsa_prefix_str = NULL;const char *spk_ext_pa = "qcom,msm-spk-ext-pa";/*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */const char *hac_pa = "qcom,msm-hac-pa";const char *hac_pa_p = "qcom,msm-hac-pa-gpio";/*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */int num_strings;...pr_debug("%s: ext_pa = %d\n", __func__, pdata->ext_pa);/*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */pdata->hac_pa_gpio = of_get_named_gpio(pdev->dev.of_node, hac_pa, 0);if (pdata->hac_pa_gpio < 0) {dev_err(&pdev->dev, "%s: missing %s in dt node\n", __func__, hac_pa);}pdata->hac_pa_gpio_p = of_parse_phandle(pdev->dev.of_node, hac_pa_p, 0);if (pdata->hac_pa_gpio_p < 0) {dev_err(&pdev->dev, "%s: missing %s in dt node\n", __func__, hac_pa_p);}/*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */pdata->spk_ext_pa_gpio = of_get_named_gpio(pdev->dev.of_node,spk_ext_pa, 0);if (pdata->spk_ext_pa_gpio < 0) { |
以上代碼就是讀取dts中的定義,那么dts中又添加了什么呢?(我是在kernel/msm-4.9/arch/arm64/boot/dts/qcom/qm215-audio.dtsi中添加的,當(dāng)然可以選擇其他地方)
| /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ &tlmm {hac_pa {hac_pa_high: hac_pa_high {mux {pins = "gpio127";function = "gpio";};config {pins = "gpio127";drive-strength = <8>; /* 8mA */bias-disable = <0>; /* no pull */output-high;};};hac_pa_low: hac_pa_low {mux {pins = "gpio127";function = "gpio";};config {pins = "gpio127";drive-strength = <2>;output-low;bias-pull-down;};};}; }; /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ &soc {qcom,msm-audio-apr {compatible = "qcom,msm-audio-apr";msm_audio_apr_dummy {compatible = "qcom,msm-audio-apr-dummy";};};qcom,avtimer@c0a300c {compatible = "qcom,avtimer";reg = <0x0c0a300c 0x4>,<0x0c0a3010 0x4>;reg-names = "avtimer_lsb_addr", "avtimer_msb_addr";qcom,clk-div = <27>;};/*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */cdc_hac_pa_gpio: msm_cdc_pinctrl@127 {compatible = "qcom,msm-cdc-pinctrl";pinctrl-names = "aud_active", "aud_sleep";pinctrl-0 = <&hac_pa_high>;pinctrl-1 = <&hac_pa_low>;};/*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */int_codec: sound {status = "okay";compatible = "qcom,msm8952-audio-codec";qcom,model = "msm8952-snd-card-mtp";reg = <0xc051000 0x4>,<0xc051004 0x4>,<0xc055000 0x4>,<0xc052000 0x4>;reg-names = "csr_gp_io_mux_mic_ctl","csr_gp_io_mux_spkr_ctl","csr_gp_io_lpaif_pri_pcm_pri_mode_muxsel","csr_gp_io_mux_quin_ctl";qcom,msm-ext-pa = "primary"; /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */qcom,msm-hac-pa = <&tlmm 127 0>;qcom,msm-hac-pa-gpio = <&cdc_hac_pa_gpio>; /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */qcom,msm-mclk-freq = <9600000>;qcom,msm-mbhc-hphl-swh = <1>;qcom,msm-mbhc-gnd-swh = <1>; |
這些添加完成之后,基本上就能通過(guò)tinyalsa去控制“HAC_PA”的On/Off了,達(dá)到想打開(kāi)GPIO_HAC_EN的時(shí)候就能打開(kāi)。
d
那么硬件的同事還有兩個(gè)需求,第一個(gè)就是配對(duì)一個(gè)acdb_id,這樣能方便他們配對(duì)調(diào)試,那么在hal層需要做什么呢?(目錄:hardware/qcom/audio)由于比較零散,也比較簡(jiǎn)單,知識(shí)點(diǎn)不多,所以直接貼上diff文件吧,這一份是比較早的代碼備份,有一點(diǎn)邏輯是有問(wèn)題的。文件直接通過(guò)git diff ./ > diff.txt導(dǎo)出來(lái)就可以了。
| diff --git a/hal/audio_hw.c b/hal/audio_hw.c index 3404dd6..bed0ec3 100644 --- a/hal/audio_hw.c +++ b/hal/audio_hw.c @@ -6866,6 +6866,23 @@ static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)status = platform_set_parameters(adev->platform, parms);if (status != 0)goto done; +/*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ + ret = str_parms_get_str(parms, "odm.hac.enable", value, sizeof(value)); + if(ret >= 0) + { + ALOGE("fuhua ---- get odm.hac.enable = %s",value); + if(strcmp(value,AUDIO_PARAMETER_VALUE_ON) == 0) + {adev->hac_enable = true;} + else + {adev->hac_enable = false;} + } + else + { + ALOGE("fuhua ---- not get the odm.hac.enable = %s",value); + } + +/*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ +ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));if (ret >= 0) { diff --git a/hal/audio_hw.h b/hal/audio_hw.h index f791b6a..3865c0f 100644 --- a/hal/audio_hw.h +++ b/hal/audio_hw.h @@ -493,6 +493,9 @@ struct audio_device {bool allow_afe_proxy_usage;bool is_charging; // from battery listenerbool mic_break_enabled; + /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ + bool hac_enable; + /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */int snd_card;card_status_t card_status; diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c index aeb3abe..7a8d94e 100644 --- a/hal/msm8916/platform.c +++ b/hal/msm8916/platform.c @@ -488,7 +488,9 @@ static const char * const device_table[SND_DEVICE_MAX] = {[SND_DEVICE_OUT_VOIP_SPEAKER] = "voip-speaker",[SND_DEVICE_OUT_VOIP_HEADPHONES] = "voip-headphones", #endif - + /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ + [SND_DEVICE_OUT_VOICE_HANDSET_HAC] = "voice-handset-hac", + /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 *//* Capture sound devices */[SND_DEVICE_IN_HANDSET_MIC] = "handset-mic",[SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = "handset-mic-ext", @@ -668,6 +670,9 @@ static int acdb_device_table[SND_DEVICE_MAX] = {[SND_DEVICE_OUT_VOIP_SPEAKER] = 132,[SND_DEVICE_OUT_VOIP_HEADPHONES] = 134, #endif + /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ + [SND_DEVICE_OUT_VOICE_HANDSET_HAC] = 31, + /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */[SND_DEVICE_IN_HANDSET_MIC] = 4,[SND_DEVICE_IN_HANDSET_MIC_EXTERNAL] = 4, @@ -832,6 +837,10 @@ static struct name_to_index snd_device_name_index[SND_DEVICE_MAX] = {{TO_NAME_INDEX(SND_DEVICE_OUT_VOIP_SPEAKER)},{TO_NAME_INDEX(SND_DEVICE_OUT_VOIP_HEADPHONES)}, #endif + /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ + {TO_NAME_INDEX(SND_DEVICE_OUT_VOICE_HANDSET_HAC)}, + /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ + {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC)},{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_EXTERNAL)},{TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_MIC_AEC)}, @@ -4307,6 +4316,18 @@ snd_device_t platform_get_output_snd_device(void *platform, struct stream_out *osnd_device = SND_DEVICE_OUT_ANC_HANDSET;elsesnd_device = SND_DEVICE_OUT_VOICE_HANDSET; + /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ + if(adev->hac_enable == true) + { + ALOGE("fuhua --- adev->hac_enable == true"); + snd_device = SND_DEVICE_OUT_VOICE_HANDSET_HAC; + } + else + { + ALOGE("fuhua --- adev->hac_enable == false or not get value"); + snd_device = SND_DEVICE_OUT_VOICE_HANDSET_HAC; + } + /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */} else if (devices & AUDIO_DEVICE_OUT_TELEPHONY_TX)snd_device = SND_DEVICE_OUT_VOICE_TX;diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h index f37819d..e0dbcfa 100644 --- a/hal/msm8916/platform.h +++ b/hal/msm8916/platform.h @@ -150,6 +150,9 @@ enum {SND_DEVICE_OUT_VOIP_SPEAKER,SND_DEVICE_OUT_VOIP_HEADPHONES, #endif + /*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ + SND_DEVICE_OUT_VOICE_HANDSET_HAC, + /*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_HEADPHONES,SND_DEVICE_OUT_VOICE_SPEAKER_AND_VOICE_ANC_HEADSET,SND_DEVICE_OUT_VOICE_SPEAKER_STEREO_AND_VOICE_HEADPHONES, @@ -292,8 +295,10 @@ enum { #define MIXER_PATH_MAX_LENGTH 100 #define SND_CARD_MAX_LENGTH 100 #define CODEC_VERSION_MAX_LENGTH 100 - -#define MAX_VOL_INDEX 5 +/*begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ +//#define MAX_VOL_INDEX 5 +#define MAX_VOL_INDEX 7 +/*end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750 */ #define MIN_VOL_INDEX 0 #define percent_to_index(val, min, max) \((val) * ((max) - (min)) * 0.01 + (min) + .5) |
e
完成audio_test.sh中添加開(kāi)關(guān)。實(shí)際上只要打通了 HAC_PA 的path,剩下的都不難了吧。
| ###################### receiver playback test ###################### if [ $1 == 'handset' ];then # echo $$ >> /data/audio_test_receiver.pid # echo 'log log ' >> /sdcard/log.txt # setprop "tinyplay_status" "on"tinymix_v2 'PRI_MI2S_RX Audio Mixer MultiMedia1' '1'tinymix_v2 'RX1 MIX1 INP1' 'RX1'tinymix_v2 "RDAC2 MUX" 'RX1'tinymix_v2 'RX1 Digital Volume' '84'tinymix_v2 "EAR PA Gain" "POS_6_DB"tinymix_v2 "EAR_S" 'Switch'#begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750tinymix_v2 "HAC_PA" 'On'#end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750while [ "1" == "1" ]dotinyplay_v2 /system/etc/112.wav -d 0done fiif [ $1 == 'handset-stop' ];then # setprop "tinyplay_status" "off" # if [ -f /data/audio_test_receiver.pid ];then # pid=`cat /data/audio_test_receiver.pid` # kill -9 $pid # rm /data/audio_test_receiver.pid # fi#begin mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750tinymix_v2 "HAC_PA" 'Off'#end mod by fuhua for task: 8668750 on 2019-12-03 task id :8668750tinymix_v2 'RX1 MIX1 INP1' '0'tinymix_v2 "RDAC2 MUX" 'ZERO'tinymix_v2 'RX1 Digital Volume' '67'tinymix_v2 "EAR PA Gain" 'POS_1P5_DB'tinymix_v2 "EAR_S" 'ZERO'tinymix_v2 'PRI_MI2S_RX Audio Mixer MultiMedia1' '0' fi |
結(jié)語(yǔ)
我在自己調(diào)試的時(shí)候發(fā)現(xiàn),單單的沒(méi)有tinymix_v2 "EAR PA Gain" "POS_6_DB"增益的設(shè)置,打電話的時(shí)候是不會(huì)出聲的,向硬件同事請(qǐng)教,說(shuō)是由于電信號(hào)轉(zhuǎn)磁信號(hào)效率低,而hac器件還得從磁信號(hào)又轉(zhuǎn)一遍電信號(hào),那更低了;而電信號(hào)轉(zhuǎn)機(jī)械信號(hào)效率相對(duì)較高,即Receiver能出聲而hac器件不能出聲的道理。
總結(jié)
以上是生活随笔為你收集整理的Android - Audio - Qcom平台 - hac器件bring up的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 博士申请 | 美国范德堡大学NDS实验室
- 下一篇: Android,firefly3399开