• Android底层音频声道耳机插头和开关壳体的发展


    Android潜在的发展耳机插头连接到音频频道切换的例子


           因为使用的是耳机 麦克分离式的耳机,所以要分别上报事件。在Android系统层耳机插孔的检測是基于/sys/class/switch/h2w/state的值来推断的(以4.4.4_r2为样例位于WiredAccessoryManager.java)。

     

           仅仅要在内核中实现一个「或真或假」的基于switch类的h2w开关。Android系统就能够监听到插拔信息。

           在播放音乐的时候插入耳机,使用tinymix(參考:Android音频底层调试-基于tinyalsa)命令能够查找到Playback Path的值从SPK变为HP_NO_MIC,就能够说明耳机插拔软件检測正常了。

    # tinymix                                                        

    Mixer name: 'RK_RK616_TINY'

    Number of controls: 7

    ctl type num name                                     value

    0 ENUM 1 Playback Path                            HP_NO_MIC

    1 ENUM 1 Capture MIC Path                         MIC OFF

    2 ENUM 1 Voice Call Path                          OFF

    3 ENUM 1 Voip Path                                 OFF

    4 INT 2 Speaker Playback Volume                  24 24

    5 INT 2 Headphone Playback Volume                24 24

    6 ENUM 1 Modem Input Enable                       ON


           可是喇叭还在响,说明没有被关闭。查查原理图「功放上的控制脚」是在哪个GPIO上接着呢。

     

           依据手冊得出仅仅要GPIO2_D7能够输出低电平就能实现喇叭的关闭,使用万用表測得在插入耳机后该管脚仍然为高电平。查看代码改动记录在上一个版本号同事是直接在rk_headset.c耳机插拔程序中改动将其拉低的,这样能够实现可是认为不妥。Android上层应该也是有音频通道切换的。依据上层来控制比較好。

    这样插入耳机的时候也能够强制开启喇叭。把「使用哪个音频通信的决定权」交给给用户。

           这个应该是在内核中实现的,由于Alsa已经正常切换了,就说明上层已经调用对应的接口了。从驱动中来分析。

    设备资源:能够看到Speakhandphone的使能GPIO都给的是RK30_PIN2_PD7

    static struct rk616_platform_data rk616_pdata = {

            .power_init = rk616_power_on_init,

            .power_deinit = rk616_power_deinit,

            .scl_rate   = RK616_SCL_RATE,

            .lcd0_func = INPUT,             //port lcd0 as input

            .lcd1_func = INPUT,             //port lcd1 as input

            .lvds_ch_nr = 1,                //the number of used lvds channel  

            .hdmi_irq = RK30_PIN2_PD6,

            .spk_ctl_gpio = RK30_PIN2_PD7,

            .hp_ctl_gpio = RK30_PIN2_PD7,

    };

    设备驱动中控制音频输出通道的函数:

    static int rk616_playback_path_put(struct snd_kcontrol *kcontrol,

                    struct snd_ctl_elem_value *ucontrol)

    {

            ......

            case HP_PATH:

            case HP_NO_MIC:

            case RING_HP:

            case RING_HP_NO_MIC:

                    rk616_set_gpio(RK616_CODEC_SET_SPKGPIO_LOW);

                    

                    if (pre_path == OFF)

                            rk616_codec_power_up(RK616_CODEC_PLAYBACK);

     

                    snd_soc_update_bits(codec, RK616_SPKL_CTL,

                            RK616_VOL_MASK, HPOUT_VOLUME); //, volume (bit 0-4)

                    snd_soc_update_bits(codec, RK616_SPKR_CTL,

                            RK616_VOL_MASK, HPOUT_VOLUME);

     

                    rk616_set_gpio(RK616_CODEC_SET_HPGPIO_HIGH);

                    break;

            ......

    }

           可见在输出到耳机通道时,禁用 SPEAKER和使能HP都是设置的GPIO_HIGH,最后RK30_PIN2_PD7仍然为高电平,没有禁用SPEAKER。原理图并没有单独的耳机的使能管脚。在资源中将hp_ctl_gpio设置为INVALID_GPIO。问题得以解决。

    额外收获:原理耳机那里一直都是有音频输出的,不管插入不插入耳机;插入耳机时不过将SPEAKER禁止了。

    误入的歧途:

    1.误以为要去看Android上层代码在各种类中追寻了非常久。真是浪费时间,假设使用tinymix查看音频通道切换正常,说明内核以上的都没有问题了,出问题也是出在了内核以及硬件上。

    总结:庞大的Android系统容不得你每一块都了解的非常仔细,可是假设会非常好的划分层次。问题就会非常好解决。记录的重点不在于详细的型号版本号等等比較虚拟方面,但是,在这样的问题善于分析的头脑面对。

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    Centos7安装Redis-单节点
    解决物理机U盘安装Kali Linux2018.1,光驱无法加载问题
    做销售如何跟单,逼单!共20招!(转)
    销售沟通技巧(转)
    rails gem (2015-07-16)
    Foundation
    Redis TTL 为0
    Introspection反射机制
    will_paginate
    Linux下Rsync+Inotify-tools实现数据实时同步
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4740102.html
Copyright © 2020-2023  润新知