RK3399 android7.1 耳机拔插ADC检测

rk3399_android7.1耳机拔插ADC检测 平仄散人

ADC 使用

一.frameworks\base\services\core\java\com\android\server\WiredAccessoryManager.java

1
2
3
4
5
6
7
8
9
10
11
private static final String HEADSET_CONNECTION_NODE  =  "/sys/devices/virtual/switch/h2w/state";
 
            public String getDevName() { return mDevName; }
 
            public String getDevPath() {
                return String.format(Locale.US, "/devices/virtual/switch/%s", mDevName);
            }
 
            public String getSwitchStatePath() {
                return String.format(Locale.US, "/sys/class/switch/%s/state", mDevName);
            }

  

 二.驱动解析

2.1.dts 配置 

1
2
3
4
5
6
7
rockchip_headset {
            status = "okay";
            compatible = "rockchip_headset";
            io-channels = <&saradc 2>;
    io-channel-names = "headset";
            headset_gpio = <&gpio0 8 GPIO_ACTIVE_LOW>;
};  

 

2.2.kernel\drivers\headset_observe\rockchip_headset_core.c

ret = of_get_named_gpio_flags(node, "headset_gpio", 0, &flags); //解析gpio
如果解析到gpio就devm_gpio_request //申请GPIO,gpio_direction_input//设置GPIO口为输入状态

of_get_named_gpio_flags(node, "hook_gpio", 0, &pdata->hook_gpio); //解析GPIO
如果解析不到GPIO就 pdata->chan = iio_channel_get(&pdev->dev, NULL); //获取ADC通道

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
static int rockchip_headset_probe(struct platform_device *pdev)
{
    struct device_node *node = pdev->dev.of_node;
    struct rk_headset_pdata *pdata;
    int ret,i,val;
    //enum of_gpio_flags flags;
 
    pdata = kzalloc(sizeof(struct rk_headset_pdata), GFP_KERNEL);
    if (pdata == NULL) {
        printk("%s failed to allocate driver data\n",__FUNCTION__);
        return -ENOMEM;
    }
    memset(pdata,0,sizeof(struct rk_headset_pdata));
    pdata_info = pdata;
 
    //headset
    ret = of_get_named_gpio(node, "headset_gpio", 0);
    if (ret < 0) {
        printk("%s() Can not read property headset_gpio\n", __FUNCTION__);
        goto err;
    } else {
        pdata->headset_gpio = ret;
        ret = devm_gpio_request(&pdev->dev, pdata->headset_gpio, "headset_gpio");
        if(ret < 0){
            printk("%s() devm_gpio_request headset_gpio request ERROR\n", __FUNCTION__);
            goto err;
        }
 
        ret = gpio_direction_input(pdata->headset_gpio);
        if(ret < 0){
            printk("%s() gpio_direction_input headset_gpio set ERROR\n", __FUNCTION__);
            goto err;
        }
 
        pdata->headset_insert_type = HEADSET_IN_LOW;
    }
    pdata->chan = iio_channel_get(&pdev->dev, NULL);
    if (IS_ERR(pdata->chan))
    {
            pdata->chan = NULL;
            printk("%s() have not set adc chan\n", __FUNCTION__);
    }
    set_headset_mic_power(1);
     
    for(i = 0;i < 5;i++){
        ret = iio_read_channel_raw(pdata->chan, &val);
          if (ret < 0)
          {
                pr_err("timer_work_callback read adc channel() error: %d\n", ret);
          }
          msleep(100);         
    }  
    printk("eric  222 iio_read_channel_raw = %d \n",val);  
     
    if(val > 5)
    {
        printk("%s() ZK-R39A V1.1\n",__FUNCTION__);
        ret = rk_headset_adc_probe(pdev,pdata);
        if(ret < 0)
        {
            goto err;
        }  
 
    }
    else
    {
        printk("%s() ZK-R39A V1.0\n",__FUNCTION__);
        ret = rk_headset_probe(pdev,pdata);
        if(ret < 0)
        {
            goto err;
        }
    }
 
    return 0;
err:
    kfree(pdata);
    return ret;
}

2.3.kernel\drivers\headset_observe\rk_headset_irq_hook_adc.c

读取 AD 采集到的原始数据
int value,Vresult;
ret = iio_read_channel_raw(chan, &value);
调用 iio_read_channel_raw 函数读取 AD 采集的原始数据并存入value变量中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
static void hook_once_work(struct work_struct *work)
{
    int ret,val;
 
    #ifdef CONFIG_SND_SOC_WM8994
    wm8994_headset_mic_detect(true);
    #endif
 
    #if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
    rt3261_headset_mic_detect(true);
    #endif
 
    #ifdef CONFIG_SND_SOC_RT5631_PHONE
    rt5631_headset_mic_detect(true);
    #endif
 
  ret = iio_read_channel_raw(headset_info->chan, &val);
  if (ret < 0) {
        pr_err("read hook_once_work adc channel() error: %d\n", ret);
    }else
        DBG("hook_once_work read adc value: %d\n",val);
 
    if(val >= 800 && val < 1000)
    {
        headset_info->isMic= 0;//No microphone
        #ifdef CONFIG_SND_SOC_WM8994
        wm8994_headset_mic_detect(false);
        #endif
 
        #if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224)
        rt3261_headset_mic_detect(false);
        #endif 
 
        #ifdef CONFIG_SND_SOC_RT5631_PHONE
        rt5631_headset_mic_detect(false);
        #endif                 
    }  
    else if(val >= 550 && val < 750)
    {
        headset_info->isMic = 1;//four headseet in
    }
    else if(val >= 5 && val < 100)
    {
        headset_info->isMic = 1;//three headseet in
    }  
 
    headset_info->cur_headset_status = headset_info->isMic ? 1:0;
 
    #if defined(CONFIG_SND_SOC_CX2072X)
    if (cx2072x_jack_report() != -1)
        headset_info->cur_headset_status =
            (cx2072x_jack_report() == 3) ?
            BIT_HEADSET : BIT_HEADSET_NO_MIC;
    #endif
     
    switch_set_state(&headset_info->sdev, headset_info->cur_headset_status); 
    DBG("%s notice android headset status = %d\n",__func__,headset_info->cur_headset_status);
    schedule_delayed_work(&headset_info->h_delayed_work[HOOK],msecs_to_jiffies(500));
}

  

  

posted @   CrushGirl  阅读(961)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示