




已阅读5页,还剩21页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
android button light 流程分析(一) driver 一、led-classled-class是button light driver的核心层,代码位于drivers/leds/目录下,提供了一些数据结构和接口,其中创建了一个leds设备类,用于管理系统所有的led,代码如下:cpp view plaincopyprint?1. staticint_initleds_init(void)2. 3. leds_class=class_create(THIS_MODULE,leds);4. if(IS_ERR(leds_class)5. returnPTR_ERR(leds_class);6. leds_class-suspend=led_suspend;7. leds_class-resume=led_resume;8. return0;9. 10. 11. staticvoid_exitleds_exit(void)12. 13. class_destroy(leds_class);14. 15. 16. subsys_initcall(leds_init);17. module_exit(leds_exit);static int _init leds_init(void)leds_class = class_create(THIS_MODULE, leds);if (IS_ERR(leds_class)return PTR_ERR(leds_class);leds_class-suspend = led_suspend;leds_class-resume = led_resume;return 0;static void _exit leds_exit(void)class_destroy(leds_class);subsys_initcall(leds_init);module_exit(leds_exit);创建成功后我们可以在/sys/class目录下面看到leds目录,并注册了统一的休眠和唤醒函数: cpp view plaincopyprint?1. /*2. *led_classdev_suspend-suspendanled_classdev.3. *led_cdev:theled_classdevtosuspend.4. */5. voidled_classdev_suspend(structled_classdev*led_cdev)6. 7. led_cdev-flags|=LED_SUSPENDED;8. led_cdev-brightness_set(led_cdev,0);9. 10. EXPORT_SYMBOL_GPL(led_classdev_suspend);11. 12. /*13. *led_classdev_resume-resumeanled_classdev.14. *led_cdev:theled_classdevtoresume.15. */16. voidled_classdev_resume(structled_classdev*led_cdev)17. 18. led_cdev-brightness_set(led_cdev,led_cdev-brightness);19. led_cdev-flags&=LED_SUSPENDED;20. 21. EXPORT_SYMBOL_GPL(led_classdev_resume);22. 23. staticintled_suspend(structdevice*dev,pm_message_tstate)24. 25. structled_classdev*led_cdev=dev_get_drvdata(dev);26. 27. if(led_cdev-flags&LED_CORE_SUSPENDRESUME)28. led_classdev_suspend(led_cdev);29. 30. return0;31. 32. 33. staticintled_resume(structdevice*dev)34. 35. structled_classdev*led_cdev=dev_get_drvdata(dev);36. 37. if(led_cdev-flags&LED_CORE_SUSPENDRESUME)38. led_classdev_resume(led_cdev);39. 40. return0;41. /* * led_classdev_suspend - suspend an led_classdev. * led_cdev: the led_classdev to suspend. */void led_classdev_suspend(struct led_classdev *led_cdev)led_cdev-flags |= LED_SUSPENDED;led_cdev-brightness_set(led_cdev, 0);EXPORT_SYMBOL_GPL(led_classdev_suspend);/* * led_classdev_resume - resume an led_classdev. * led_cdev: the led_classdev to resume. */void led_classdev_resume(struct led_classdev *led_cdev)led_cdev-brightness_set(led_cdev, led_cdev-brightness);led_cdev-flags &= LED_SUSPENDED;EXPORT_SYMBOL_GPL(led_classdev_resume);static int led_suspend(struct device *dev, pm_message_t state)struct led_classdev *led_cdev = dev_get_drvdata(dev);if (led_cdev-flags & LED_CORE_SUSPENDRESUME)led_classdev_suspend(led_cdev);return 0;static int led_resume(struct device *dev)struct led_classdev *led_cdev = dev_get_drvdata(dev);if (led_cdev-flags & LED_CORE_SUSPENDRESUME)led_classdev_resume(led_cdev);return 0;suspend主要设置一下标志并将led关闭,resume主要清除标志并将led恢复之前亮度。同时led-class提供了结构体led_classdev作为统一的led设备模型: cpp view plaincopyprint?1. structled_classdev2. constchar*name;3. intbrightness;4. intmax_brightness;5. intflags;6. 7. /*Lower16bitsreflectstatus*/8. #defineLED_SUSPENDED(10) 9. /*Upper16bitsreflectcontrolinformation*/10. #defineLED_CORE_SUSPENDRESUME(116) 11. 12. /*SetLEDbrightnesslevel*/13. /*Mustnotsleep,useaworkqueueifneeded*/14. void(*brightness_set)(structled_classdev*led_cdev,15. enumled_brightnessbrightness);16. /*GetLEDbrightnesslevel*/17. enumled_brightness(*brightness_get)(structled_classdev*led_cdev);18. 19. /*Activatehardwareacceleratedblink,delaysarein20. *milisecondsandifnoneisprovidedthenasensibledefault21. *shouldbechosen.Thecallcanadjustthetimingsifitcant22. *matchthevaluesspecifiedexactly.*/23. int(*blink_set)(structled_classdev*led_cdev,24. unsignedlong*delay_on,25. unsignedlong*delay_off);26. 27. structdevice*dev;28. structlist_headnode;/*LEDDevicelist*/29. constchar*default_trigger;/*Triggertouse*/30. 31. #ifdefCONFIG_LEDS_TRIGGERS 32. /*Protectsthetriggerdatabelow*/33. structrw_semaphoretrigger_lock;34. 35. structled_trigger*trigger;36. structlist_headtrig_list;37. void*trigger_data;38. #endif 39. ;struct led_classdev const char*name;int brightness;int max_brightness;int flags;/* Lower 16 bits reflect status */#define LED_SUSPENDED(1 0)/* Upper 16 bits reflect control information */#define LED_CORE_SUSPENDRESUME(1 brightness_get)4. led_cdev-brightness=led_cdev-brightness_get(led_cdev);5. 6. 7. staticssize_tled_brightness_show(structdevice*dev,8. structdevice_attribute*attr,char*buf)9. 10. structled_classdev*led_cdev=dev_get_drvdata(dev);11. 12. /*nolockneededforthis*/13. led_update_brightness(led_cdev);14. 15. returnsprintf(buf,%un,led_cdev-brightness);16. 17. 18. staticssize_tled_brightness_store(structdevice*dev,19. structdevice_attribute*attr,constchar*buf,size_tsize)20. 21. structled_classdev*led_cdev=dev_get_drvdata(dev);22. ssize_tret=-EINVAL;23. char*after;24. unsignedlongstate=simple_strtoul(buf,&after,10);25. size_tcount=after-buf;26. 27. if(*after&isspace(*after)28. count+;29. 30. if(count=size)31. ret=count;32. 33. if(state=LED_OFF)34. led_trigger_remove(led_cdev);35. led_set_brightness(led_cdev,state);36. 37. 38. returnret;39. 40. 41. staticssize_tled_max_brightness_show(structdevice*dev,42. structdevice_attribute*attr,char*buf)43. 44. structled_classdev*led_cdev=dev_get_drvdata(dev);45. 46. returnsprintf(buf,%un,led_cdev-max_brightness);47. 48. 49. staticDEVICE_ATTR(brightness,0644,led_brightness_show,led_brightness_store);50. staticDEVICE_ATTR(max_brightness,0444,led_max_brightness_show,NULL);static void led_update_brightness(struct led_classdev *led_cdev)if (led_cdev-brightness_get)led_cdev-brightness = led_cdev-brightness_get(led_cdev);static ssize_t led_brightness_show(struct device *dev, struct device_attribute *attr, char *buf)struct led_classdev *led_cdev = dev_get_drvdata(dev);/* no lock needed for this */led_update_brightness(led_cdev);return sprintf(buf, %un, led_cdev-brightness);static ssize_t led_brightness_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t size)struct led_classdev *led_cdev = dev_get_drvdata(dev);ssize_t ret = -EINVAL;char *after;unsigned long state = simple_strtoul(buf, &after, 10);size_t count = after - buf;if (*after & isspace(*after)count+;if (count = size) ret = count;if (state = LED_OFF)led_trigger_remove(led_cdev);led_set_brightness(led_cdev, state);return ret;static ssize_t led_max_brightness_show(struct device *dev,struct device_attribute *attr, char *buf)struct led_classdev *led_cdev = dev_get_drvdata(dev);return sprintf(buf, %un, led_cdev-max_brightness);static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);其中brightness主要用于设置和读取亮度值,max_brightness则用于读取硬件支持的最大亮度值。led-class还提供了注册led_classdev的统一接口: cpp view plaincopyprint?1. /*2. *led_classdev_register-registeranewobjectofled_classdevclass.3. *parent:Thedevicetoregister.4. *led_cdev:theled_classdevstructureforthisdevice.5. */6. intled_classdev_register(structdevice*parent,structled_classdev*led_cdev)7. 8. intrc;9. 10. led_cdev-dev=device_create(leds_class,parent,0,led_cdev,11. %s,led_cdev-name);/在leds_class下创建设备 12. if(IS_ERR(led_cdev-dev)13. returnPTR_ERR(led_cdev-dev);14. 15. /*创建brightness属性文件*/16. rc=device_create_file(led_cdev-dev,&dev_attr_brightness);17. if(rc)18. gotoerr_out;19. 20. #ifdefCONFIG_LEDS_TRIGGERS 21. init_rwsem(&led_cdev-trigger_lock);22. #endif 23. /*将该设备添加到链表leds_list*/24. down_write(&leds_list_lock);25. list_add_tail(&led_cdev-node,&leds_list);26. up_write(&leds_list_lock);27. 28. if(!led_cdev-max_brightness)29. led_cdev-max_brightness=LED_FULL;30. 31. rc=device_create_file(led_cdev-dev,&dev_attr_max_brightness);32. if(rc)33. gotoerr_out_attr_max;34. 35. led_update_brightness(led_cdev);/更新亮度值 36. 37. #ifdefCONFIG_LEDS_TRIGGERS 38. rc=device_create_file(led_cdev-dev,&dev_attr_trigger);39. if(rc)40. gotoerr_out_led_list;41. 42. led_trigger_set_default(led_cdev);43. #endif 44. 45. printk(KERN_INFORegisteredleddevice:%sn,46. led_cdev-name);47. 48. return0;49. 50. #ifdefCONFIG_LEDS_TRIGGERS 51. err_out_led_list:52. device_remove_file(led_cdev-dev,&dev_attr_max_brightness);53. #endif 54. err_out_attr_max:55. device_remove_file(led_cdev-dev,&dev_attr_brightness);56. list_del(&led_cdev-node);57. err_out:58. device_unregister(led_cdev-dev);59. returnrc;60. 61. EXPORT_SYMBOL_GPL(led_classdev_register);/* * led_classdev_register - register a new object of led_classdev class. * parent: The device to register. * led_cdev: the led_classdev structure for this device. */int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)int rc;led_cdev-dev = device_create(leds_class, parent, 0, led_cdev, %s, led_cdev-name); / 在leds_class下创建设备if (IS_ERR(led_cdev-dev)return PTR_ERR(led_cdev-dev);/* 创建brightness属性文件 */rc = device_create_file(led_cdev-dev, &dev_attr_brightness);if (rc)goto err_out;#ifdef CONFIG_LEDS_TRIGGERSinit_rwsem(&led_cdev-trigger_lock);#endif/* 将该设备添加到链表leds_list */down_write(&leds_list_lock);list_add_tail(&led_cdev-node, &leds_list);up_write(&leds_list_lock);if (!led_cdev-max_brightness)led_cdev-max_brightness = LED_FULL;rc = device_create_file(led_cdev-dev, &dev_attr_max_brightness);if (rc)goto err_out_attr_max;led_update_brightness(led_cdev); / 更新亮度值#ifdef CONFIG_LEDS_TRIGGERSrc = device_create_file(led_cdev-dev, &dev_attr_trigger);if (rc)goto err_out_led_list;led_trigger_set_default(led_cdev);#endifprintk(KERN_INFO Registered led device: %sn,led_cdev-name);return 0;#ifdef CONFIG_LEDS_TRIGGERSerr_out_led_list:device_remove_file(led_cdev-dev, &dev_attr_max_brightness);#endiferr_out_attr_max:device_remove_file(led_cdev-dev, &dev_attr_brightness);list_del(&led_cdev-node);err_out:device_unregister(led_cdev-dev);return rc;EXPORT_SYMBOL_GPL(led_classdev_register);二、led-driver在平台的驱动中我们注册一个platform led设备作为所有led设备的父设备,注册代码如下: cpp view plaincopyprint?1. staticstructplatform_driveratxxled_driver=2. .probe=atxxled_probe,3. .remove=atxxled_remove,4. .driver=5. .name=led,6. .owner=THIS_MODULE,7. ,8. ;9. 10. staticint_initatxxled_init(void)11. 12. returnplatform_driver_register(&atxxled_driver);13. 14. 15. staticvoid_exitatxxled_exit(void)16. 17. platform_driver_unregister(&atxxled_driver);18. 19. 20. module_init(atxxled_init);21. module_exit(atxxled_exit);static struct platform_driver atxxled_driver = .probe = atxxled_probe,.remove = atxxled_remove,.driver = .name = led,.owner = THIS_MODULE,;static int _init atxxled_init(void)return platform_driver_register(&atxxled_driver);static void _exit atxxled_exit(void)platform_driver_unregister(&atxxled_driver);module_init(atxxled_init);module_exit(atxxled_exit);然后再分别注册每一个led: cpp view plaincopyprint?1. staticvoidatxxled_set(structled_classdev*led_cdev,enumATXX_LEDled,2. enumled_brightnessvalue)3. 4. intis_on=(value=LED_OFF)?0:1;5. enumpmu_led_moduleled_module;6. switch(led)7. caseRED_LED:8. led_module=PMU_LED_MODULE_2;9. break;10. caseGREEN_LED:11. led_module=PMU_LED_MODULE_1;12. break;13. default:14. return;15. break;16. 17. pmu_led_on_off_set(led_module,is_on,0);/led电源控制接口 18. 19. 20. staticvoidatxxled_green_set(structled_classdev*led_cdev,21. enumled_brightnessvalue)22. 23. atxxled_set(led_cdev,GREEN_LED,value);24. 25. 26. staticvoidatxxled_red_set(structled_classdev*led_cdev,27. enumled_brightnessvalue)28. 29. atxxled_set(led_cdev,RED_LED,value);30. 31. 32. staticvoidatxxled_buttons_set(structled_classdev*led_cdev,33. enumled_brightnessvalue)34. 35. enumpower_supply_modeis_on=(value=LED_OFF)?PPS_OFF:PPS_ON;36. pmu_led_on_off_set(PMU_LED_KEY_1,is_on,40);37. 38. 39. staticintatxxled_blink_set(structled_classdev*led_cdev,enumATXX_LEDled,40. unsignedlong*delay_on,unsignedlong*delay_off)41. 42. enumpmu_led_moduleled_module;43. switch(led)44. caseRED_LED:45. led_module=PMU_LED_MODULE_2;46. break;47. caseGREEN_LED:48. led_module=PMU_LED_MODULE_1;49. break;50. default:51. return0;52. break;53. 54. pmu_led_blink_set(led_module,delay_on,delay_off);/led闪烁控制接口 55. return0;56. 57. 58. staticintatxxled_green_blink_set(structled_classdev*led_cdev,59. unsignedlong*delay_on,unsignedlong*delay_off)60. 61. returnatxxled_blink_set(led_cdev,GREEN_LED,delay_on,delay_off);62. 63. 64. staticintatxxled_red_blink_set(structled_classdev*led_cdev,65. unsignedlong*delay_on,unsignedlong*delay_off)66. 67. returnatxxled_blink_set(led_cdev,RED_LED,delay_on,delay_off);68. 69. 70. staticintatxxled_buttons_blink_set(structled_classdev*led_cdev,71. unsignedlong*delay_on,unsignedlong*delay_off)72. 73. return-1;74. 75. 76. staticstructled_classdevatxx_red_led=77. .name=red,78. .brightness_set=atxxled_red_set,79. .blink_set=atxxled_red_blink_set,80. .flags=0,81. ;82. 83. staticstructled_classdevatxx_green_led=84. .name=green,85. .brightness_set=atxxled_green_set,86. .blink_set=atxxled_green_blink_set,87. .flags=0,88. ;89. 90. staticstructled_classdevatxx_buttons_led=91. .name=button-backlight,92. .brightness_set=atxxled_buttons_set,/led亮度调节 93. .blink_set=atxxled_buttons_blink_set,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 蔬菜储藏知识培训课件
- 蔬菜保鲜知识培训内容课件
- 2025年中考化学试题分类汇编:工艺流程题(第1期)解析版
- 写作:如何突出中心(说课稿) 七年级语文上册同步备课系列(统编版)
- 2025年天津市河西区中考三模物理试题(解析版)
- 四年级英语下册 Unit 3 At the zoo Part B第一课时说课稿2 人教PEP
- 蒸制食品技术知识培训
- 2025福州租房合同范本
- 2025年媒体传播学职业技能资格知识考试题与答案
- 2025物业公司劳动合同样本
- GB/T 15566.9-2012公共信息导向系统设置原则与要求第9部分:旅游景区
- GB/T 152.2-2014紧固件沉头螺钉用沉孔
- 幼儿园中班绘本:《我喜欢我的小毯子》
- 改革开放以来教育方面的变化课件
- DB44-T 2197-2019配电房运维服务规范-(高清现行)
- 山西省运城市各县区乡镇行政村村庄村名居民村民委员会明细
- 河西走廊课件
- 第2课 绘画作品中的劳动者 课件 五年级美术上册 岭南版(共15张PPT)
- (高职)电子商务英语电子课件教学PPT(完整版)
- 牙龈出血牙龈肥大
- 汽车机械基础(全套课件)
评论
0/150
提交评论