經過上面步驟已經可以正確傳遞keypad event並且透過evdev read function讀到key code. 透過key code可以再control led or pwm device.
透過led.h 中的led_trigger_register_simple以及led_trigger_event便可以trigger event set led brightness.
Sample: evdev.c #includestruct led_trigger *test_led_trigger = 0; static int __init evdev_init(void) { led_trigger_register_simple("debug-leds", &test_led_trigger); //註冊test_led_trigger的trigger led label是debug-leds return input_register_handler(&evdev_handler); } static void __exit evdev_exit(void) { led_trigger_unregister_simple(test_led_trigger); test_led_trigger = 0; input_unregister_handler(&evdev_handler); } 在device tree中宣告 leds { debug-leds { gpios = <&gpio1 2 0>; linux,default-trigger = "debug-leds"; default-state = "off"; }; }; 接著回到evdev.c static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { … //此處會讀input event的data while (read + input_event_size() <= count && evdev_fetch_next_event(client, &event)) { printk("event type = %x, code = %x, value = %x\n",event.type, event.code, event.value); if(event.code == 0x1c){ //key code is "enter" printk("key code is 0x1c\n"); led_trigger_event(test_led_trigger, LED_FULL); //設定test_led_trigger control 的led 亮度為FULL(255) } read += input_event_size(); } … }
如此在收到特定key code時, "gpio1 2"這顆led便會被開到全亮.
這邊要注意的是若要控制的是pwm device, 那需要先將device宣告為pwm-leds就一樣可以使用led trigger來控制. 只需在led_trigger_event第二個arguments填入0-255的數字就可以設定pwm cycle.
詳細code流程如下
這邊要注意的是若要控制的是pwm device, 那需要先將device宣告為pwm-leds就一樣可以使用led trigger來控制. 只需在led_trigger_event第二個arguments填入0-255的數字就可以設定pwm cycle.
device tree example: pwmleds { compatible = "pwm-leds"; backlightk { label = "backlight-leds"; pwms = <&pwm1 0 8333333>; linux,default-trigger = "debug-leds"; max-brightness = <255>; }; }; 255>
詳細code流程如下
led_triggers.c void led_trigger_register_simple(const char *name, struct led_trigger **tp) { struct led_trigger *trig; int err; trig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); if (trig) { trig->name = name; err = led_trigger_register(trig); //將led_trigger建立到list中 if (err < 0) { kfree(trig); … } Trigger event時 void led_trigger_event(struct led_trigger *trig, enum led_brightness brightness) { struct list_head *entry; if (!trig) return; read_lock(&trig->leddev_list_lock); list_for_each(entry, &trig->led_cdevs) { //search list to find the trigger struct led_classdev *led_cdev; led_cdev = list_entry(entry, struct led_classdev, trig_list); led_set_brightness(led_cdev, brightness); //找到device之後最終調用device driver的brightness_set做亮度設定 } read_unlock(&trig->leddev_list_lock); }
Reference:
https://blog.csdn.net/yueqian_scut/article/details/47903853
https://blog.csdn.net/yueqian_scut/article/details/48026955
https://blog.csdn.net/qq_695538007/article/details/9153099
https://blog.csdn.net/qq_695538007/article/details/9153135
http://www.jollen.org/blog/2009/04/linux_input_device_apis.html
https://patchwork.kernel.org/patch/2848259/
https://community.nxp.com/thread/343346
Test tool:
https://cgit.freedesktop.org/evtest/