RK3399 android7.1 耳机拔插ADC检测
rk3399_android7.1耳机拔插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 )); } |
分类:
RockChip
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 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】