在 Android 中添加了一个 switch 驱动,用于监测一些开关的变化,例如:HDMI、耳机的插拔检测之类的。

驱动源码存在内核源码的 drivers/switch 中,目录下有两个主要文件:switch_class.c 和switch_gpio.c,在 switch_class.c 中创建了 switch 设备类

static int create_switch_class(void)

实现了设备注册

int switch_dev_register(struct switch_dev *sdev)

在这个函数中,会创建两个文件,一个是保存状态的文件,一个是保存名称的文件,其中状态就开关量的表现,在这个文件中还有一个改变状态的方法

 ret = device_create_file(sdev->dev, &dev_attr_state);if (ret < 0)goto err_create_file_1;ret = device_create_file(sdev->dev, &dev_attr_name);if (ret < 0)goto err_create_file_2;

这个 switch_gpio.c 文件中,就是实现了一个由 GPIO 变化来触发的 switch 动作,当设备匹配上时,会注册一个 GPIO 中断,在中断处理函数中,可以看到它会先获取gpio的值,然后设置switch的状态

static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
{struct gpio_switch_data *switch_data =(struct gpio_switch_data *)dev_id;schedule_work(&switch_data->work);return IRQ_HANDLED;
}
static void gpio_switch_work(struct work_struct *work)
{int state;struct gpio_switch_data  *data =container_of(work, struct gpio_switch_data, work);state = gpio_get_value(data->gpio);switch_set_state(&data->sdev, state);gpio_set_value(AUDIO_SWITCH_GPIO_NUM, (state ? AUDIO_SWITCH_OFF : AUDIO_SWITCH_ON));
}

这里要注意的是,这个GPIO中断注册的时候默认选择的是低电平触发,如果是检测耳机接入,恰好耳机接入后会将 gpio 电平直接拉低,这时中断就会一直触发,可能会导致系统死机,如果遇到这种场景可将触发条件改成边沿触发就可以了。

@@ -112,7 +112,7 @@ static int gpio_switch_probe(struct platform_device *pdev)}ret = request_irq(switch_data->irq, gpio_irq_handler,
-                         IRQF_TRIGGER_LOW, pdev->name, switch_data);
+                         (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING), pdev->name, switch_data);if (ret < 0)goto err_request_irq;

下面代码实现耳机检测的功能,注册了一个 h2w 的 switch 驱动

#include <linux/module.h>
#include <linux/switch.h>
#include <linux/platform_device.h>#define H2W_SWITCH_GPIO_NUM   22static struct gpio_switch_platform_data pdata = {.name      = "h2w",.gpio      = H2W_SWITCH_GPIO_NUM,.name_on   = "1",.name_off  = "0",.state_on  = "1",.state_off = "0",
};static struct platform_device h2w_switch_dev = {.name = "switch-gpio",.dev = {.platform_data = &pdata,},
};static int __init h2w_switch_init(void) {return platform_device_register(&h2w_switch_dev);
}static void __exit h2w_switch_exit(void) {platform_device_unregister(&h2w_switch_dev);
}module_init(h2w_switch_init);
module_exit(h2w_switch_exit);

为什么命名为 h2w ?

原因是 Android 已经给铺好路了,Android 有一个 有线访问管理 机制

frameworks/base/services/core/java/com/android/server/WiredAccessoryManager.java,这里默认就定义了三种类型设备访问并进行管理,其中包括h2w、usb、hdmi,h2w 就是指的有线耳机。

private List<UEventInfo> makeObservedUEventList() {List<UEventInfo> retVal = new ArrayList<UEventInfo>();UEventInfo uei;// Monitor h2wif (!mUseDevInputEventForAudioJack) {uei = new UEventInfo(NAME_H2W, BIT_HEADSET, BIT_HEADSET_NO_MIC, BIT_LINEOUT);if (uei.checkSwitchExists()) {retVal.add(uei);} else {Slog.w(TAG, "This kernel does not have wired headset support");}}// Monitor USBuei = new UEventInfo(NAME_USB_AUDIO, BIT_USB_HEADSET_ANLG, BIT_USB_HEADSET_DGTL, 0);if (uei.checkSwitchExists()) {retVal.add(uei);} else {Slog.w(TAG, "This kernel does not have usb audio support");}// Monitor HDMI//// If the kernel has support for the "hdmi_audio" switch, use that.  It will be// signalled only when the HDMI driver has a video mode configured, and the downstream// sink indicates support for audio in its EDID.//// If the kernel does not have an "hdmi_audio" switch, just fall back on the older// "hdmi" switch instead.uei = new UEventInfo(NAME_HDMI_AUDIO, BIT_HDMI_AUDIO, 0, 0);if (uei.checkSwitchExists()) {retVal.add(uei);} else {uei = new UEventInfo(NAME_HDMI, BIT_HDMI_AUDIO, 0, 0);if (uei.checkSwitchExists()) {retVal.add(uei);} else {Slog.w(TAG, "This kernel does not have HDMI audio support");}}return retVal;
}

关于这个 有线访问管理 是如何得知这个设备的,在我们设置设置这个 switch 状态的时候可以看到,它同时发送了一个 uevent 消息,然后被上层接收后进行处理。

kobject_uevent_env(&sdev->dev->kobj, KOBJ_CHANGE, envp);

有线访问管理机制 就会告知 AudioManager 设备状态的改变

mAudioManager.setWiredDeviceConnectionState(outDevice, state, "", headsetName);

Android Switch驱动的耳机检测相关推荐

  1. Android 耳机检测原理介绍

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  2. android switch模块

    Android新增了一个switch处理模块,但是没有说明其具体用途,这里将对该模块进行详细的分析.switch是Android引进的一个新驱动,用于检测一些开关量.比如检测耳机插入和USB设备插入等 ...

  3. 解决Eclipse、Android Studio ADT AVD不能检测到手机

    解决Eclipse.Android Studio ADT AVD不能检测到手机       Android开发时,经常会使用Eclipse或者Android Studio开发工具,在使用真机调试App ...

  4. Android 图形驱动初始化

    从应用程序的角度看 OpenGL 图形系统的接口,主要包括两大部分,一部分是 EGL,它为 OpenGL 渲染准备环境:另一部分是 OpenGL,它执行图形渲染.通过这些接口构造渲染环境,并执行渲染的 ...

  5. android lcd驱动框架,LCD驱动及Framebuffer相关(转载)

    LCD驱动及Framebuffer相关 (2012-11-20 17:04) 标签:&nBSP; lcd驱动  framebuffer  io内存  分类: Android驱动模块相关 内容提 ...

  6. Android 图形驱动初始化(二十三)

    从应用程序的角度看 OpenGL 图形系统的接口,主要包括两大部分,一部分是 EGL,它为 OpenGL 渲染准备环境:另一部分是 OpenGL,它执行图形渲染.通过这些接口构造渲染环境,并执行渲染的 ...

  7. android audiorecord插上耳机录音由dmic切换到耳机录音

    板子上带有一个dmic,和一个adc,不插耳机时audiorecord默认将打开dmic录音,插上耳机时自动切换到耳机录音. 这个场景是手机上太常见了,由于是tv和盒子的芯片,默认没有对这种场景的支持 ...

  8. Android 性能优化(62)---存检测、卡顿优化、耗电优化、APK瘦身——详解篇

    Android 性能优化,内存检测.卡顿优化.耗电优化.APK瘦身--详解篇 自2008年智能时代开始,Android操作系统一路高歌,10年智能机发展之路,如今 Android 9.0 代号P  都 ...

  9. android 设备驱动

    驱动概述 说到 android 驱动是离不开 Linux 驱动的.Android 内核采用的是 Linux2.6 内核 (最近Linux 3.3 已经包含了一些 Android 代码).但 Andro ...

最新文章

  1. 排序算法三:插入排序
  2. html5实践开发教程,HTML5基础与实践教程
  3. python生成条形码
  4. __dopostback
  5. DELETE_FAILED_INTERNAL_ERROR Error while Installing APK
  6. 开源 java CMS - FreeCMS2.7 单位管理
  7. ae合成复制脚本_【脚本】AE脚本精选系列 | 合成复制脚本 True Comp Duplicator v3.9.7...
  8. 淘宝网打开很慢、特别慢的完美解决方法
  9. Java可以做什么工作
  10. 【清华大学】操作系统 陈渝——Part7 进程/线程 管理
  11. 河南大学计算机科学与技术中外合作,河南大学中外合作办学怎么样
  12. 如何使用Flashfxp上传下载文件
  13. js引用本地json文件
  14. LeGO-LOAM资料整理
  15. 把日期横杠转化为斜杠
  16. 【学堂上新】Unity UGUI 渲染 3D 对象详解
  17. 目前住院病人主要由护士护理,这样做不仅需要大量护士,而且由于不能随时观察危重病人的病情变化,还可能会延误抢救时机。某医院打算开发一个以计算机为中心的监护系统,试写出问题定义并且分析开发这个系统的可行性
  18. HDU2188——悼念512汶川大地震遇难同胞——选拔志愿者(Bash Game巴士博弈)(我去,名字肿么这么长)
  19. kindeditor上传本地图片的问题
  20. matlab获取晶粒边界,晶粒边界

热门文章

  1. 免费高清壁纸网站推荐
  2. 有关计算机的英语作文一千字,关于网络的英语作文
  3. QVariant类及QVariant与自定义数据类型转换的方法
  4. IOS 清理CALayer、CAShapeLayer的sublayers
  5. iOS 13适配汇总
  6. 时间戳转换年月日——记一次字节面试题(C++实现)
  7. 计算机二级(Python)——02数值运算函数
  8. 【python10个小实验】2、石头、剪刀、布
  9. vue 使用echarts 进行简单封装统一使用
  10. Flutter升级空安全版本注意事项