完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
Platform: Rockchip
OS: Android 6.0 Kernel: 3.10.92 Overview Rockchip针对有线耳机的驱动单独建了目录, 在kernel/drivers/headset_observe/下 rockchip_headset_core.c: 读取dts中的配置,根据配置不同决定使用adc还是普通的headset探测。 rk_headset.c: 普通方式headset驱动 rk_headset_irq_hook_adc.c: adc方式headset驱动 注册 耳机插拔事件通过switch子系统上报,目录: kernel/drivers/switch/ 通过其switch_dev_register()接口把headset注册到switch子系统中 headset->sdev.name = “h2w”; headset->sdev.print_name = h2w_print_name; ret = switch_dev_register(&headset->sdev); 这样就能在/sys下看到h2w的子目录 然后,用户空间就能收到uevent事件得知耳机设备状态有变化,从state文件读取状态得知插入还是拔出来做相应处理。 插拔状态的改变是通过switch_set_state()来实现,本质上就是通知上层并改变state文件值。 dts的配置如下 &adc { status = "okay"; rockchip_headset { compatible = "rockchip_headset"; headset_gpio = ; pinctrl-names = "default"; pinctrl-0 = ; io-channels = adc 2>; /* hook_gpio = ; hook_down_type = ; //interrupt hook key down status */ }; }; headset_gpio: gpio 中断pin . io-channels: 表示当前要使用adc以及对应的channel. hook_gpio和hook_down_type并没有定义。 插拔处理: 耳机插拔中断检测在headset_interrupt()@rk_headset_irq_hook_adc.c static irqreturn_t headset_interrupt(int irq, void *dev_id) { //休眠等待电平稳定 msleep(150); if(headset_info->headset_status == HEADSET_IN) { if(pdata->chan != 0) { //detect Hook key //驱动把耳机状态和hook key的检测都放同一个流程中处理了。 schedule_delayed_work(&headset_info->h_delayed_work[HOOK],msecs_to_jiffies(200)); } }else if(headset_info->headset_status == HEADSET_OUT) { ...... } //触发方式从电平触发改成边沿触发,这样,hook key的中断不会影响耳机的插拔电平 //而且耳机插拔也可以被检测到 if(pdata->headset_insert_type == HEADSET_IN_HIGH) irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING); else irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING); return IRQ_HANDLED; } 下半部对应的work queue是hook_once_work() static void hook_once_work(struct work_struct *work) { //通知audio codec预先处理mic #if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224) rt3261_headset_mic_detect(true); #endif //adc读取 ret = iio_read_channel_raw(headset_info->chan, &val); if (ret < 0) { pr_err("read hook_once_work adc channel() error: %dn", ret); } //没有mic的情况 if(val >= 0 && val < HOOK_LEVEL_LOW) { headset_info->isMic= 0;//No microphone #if defined (CONFIG_SND_SOC_RT3261) || defined (CONFIG_SND_SOC_RT3224) rt3261_headset_mic_detect(false); #endif } //有mic的情况 else if(val >= HOOK_LEVEL_HIGH) { headset_info->isMic = 1;//have mic //不同按键的电阻值不同,那么读到的电压也不同,hook_work_callback() //处理识别(adc 读取)。 schedule_delayed_work(&headset_info->hook_work,msecs_to_jiffies(100)); } //根据是否有mic来得知是headset还是headphone. headset_info->cur_headset_status = headset_info->isMic ? BIT_HEADSET:BIT_HEADSET_NO_MIC; //通知上层设备状态变化并改变state文件值 switch_set_state(&headset_info->sdev, headset_info->cur_headset_status); } hook key 的上报通过input 子系统实现 注册: int rk_headset_adc_probe(struct platform_device *pdev,struct rk_headset_pdata *pdata) { // Create and register the input driver. headset->input_dev = input_allocate_device(); if (!headset->input_dev) { dev_err(&pdev->dev, "failed to allocate input devicen"); ret = -ENOMEM; goto failed_free; } headset->input_dev->name = pdev->name; headset->input_dev->open = rk_hskey_open; headset->input_dev->close = rk_hskey_close; headset->input_dev->dev.parent = &pdev->dev; //input_dev->phys = KEY_PHYS_NAME; headset->input_dev->id.vendor = 0x0001; headset->input_dev->id.product = 0x0001; headset->input_dev->id.version = 0x0100; // Register the input device ret = input_register_device(headset->input_dev); if (ret) { dev_err(&pdev->dev, "failed to register input devicen"); goto failed_free_dev; } input_set_capability(headset->input_dev, EV_KEY, HOOK_KEY_CODE); } 上报: static void hook_work_callback(struct work_struct *work) { input_report_key(headset->input_dev,HOOK_KEY_CODE,headset->hook_status); input_sync(headset->input_dev); } |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1906 浏览 1 评论
synopsys 的design ware:DW_fpv_div,浮点数除法器,默认32位下,想提升覆盖率(TMAX),如果用功能case去提升覆盖率呢?
2382 浏览 1 评论
RK3588 GStreamer调试四路鱼眼摄像头四宫格显示报错
5175 浏览 1 评论
【飞凌嵌入式OK3576-C开发板体验】RKNN神经网络-YOLO图像识别
254 浏览 0 评论
【飞凌嵌入式OK3576-C开发板体验】SSH远程登录网络配置及CAN通讯
1336 浏览 0 评论
浏览过的版块 |
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 00:47 , Processed in 0.641298 second(s), Total 71, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号