"); //-->
driver.c
#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/gpio.h> #include <linux/of_gpio.h> #include <linux/interrupt.h> #include <linux/of_irq.h> #include <linux/workqueue.h> //瀹氫箟缁撴瀯浣撹〃绀烘垜浠殑鑺傜偣 struct device_node *test_device_node; struct property *test_node_property; //struct tasklet_struct key_test; // 瀹氫箟宸ヤ綔缁撴瀯浣? struct work_struct key_test; //瑕佺敵璇风殑涓柇鍙? int irq; //GPIO 缂栧彿 int gpio_nu; void test(struct work_struct *data) { int i = 100; printk("i is %d \n", i); while (i--) printk("test_key is %d \n", i); } /** * @description: 涓柇澶勭悊鍑芥暟 test_key * @param {int} irq 锛氳鐢宠鐨勪腑鏂彿 * @param {void} *args 锛? * @return {*}IRQ_HANDLED */ irqreturn_t test_key(int irq, void *args) { printk("start\n"); //tasklet_schedule(&key_test); schedule_work(&key_test); printk("end\n"); return IRQ_HANDLED; } /** * @brief beep_probe : 涓庤澶囦俊鎭眰锛堣澶囨爲锛夊尮閰嶆垚鍔熷悗鑷姩鎵ц姝ゅ嚱鏁帮紝 * @param inode : 鏂囦欢绱㈠紩 * @param file : 鏂囦欢 * @return 鎴愬姛杩斿洖 0 */ int beep_probe(struct platform_device *pdev) { int ret = 0; //杩涘叆 probe 鍑芥暟 printk("beep_probe\n"); //of_find_node_by_path 鍑芥暟閫氳繃璺緞鏌ユ壘鑺傜偣锛?test_key 鏄澶囨爲涓嬬殑鑺傜偣璺緞 test_device_node = of_find_node_by_path("/test_key"); if (test_device_node == NULL) { printk("of_find_node_by_path is error \n"); return -1; } //of_get_named_gpio 鍑芥暟鑾峰彇 GPIO 缂栧彿 gpio_nu = of_get_named_gpio(test_device_node, "gpios", 0); if (gpio_nu < 0) { printk("of_get_namd_gpio is error \n"); return -1; } gpio_direction_input(gpio_nu); //鑾峰緱涓柇鍙? //irq = gpio_to_irq(gpio_nu); irq = irq_of_parse_and_map(test_device_node, 0); printk("irq is %d \n", irq); /*鐢宠涓柇锛宨rq:涓柇鍙峰悕瀛? test_key锛氫腑鏂鐞嗗嚱鏁? IRQF_TRIGGER_RISING锛氫腑鏂爣蹇楋紝鎰忎负涓婂崌娌胯Е鍙? "test_key"锛氫腑鏂殑鍚嶅瓧 */ ret = request_irq(irq, test_key, IRQF_TRIGGER_RISING, "test_key", NULL); if (ret < 0) { printk("request_irq is error \n"); return -1; } INIT_WORK(&key_test, test); return 0; } int beep_remove(struct platform_device *pdev) { printk("beep_remove\n"); return 0; } const struct platform_device_id beep_idtable = { .name = "keys", }; const struct of_device_id of_match_table_test[] = { {.compatible = "keys"}, {}, }; struct platform_driver beep_driver = { //3. 鍦?beep_driver 缁撴瀯浣撲腑瀹屾垚浜?beep_probe 鍜?beep_remove .probe = beep_probe, .remove = beep_remove, .driver = { .owner = THIS_MODULE, .name = "beep_test", .of_match_table = of_match_table_test}, //4 .id_table 鐨勪紭鍏堢骇瑕佹瘮 driver.name 鐨勪紭鍏堢骇瑕侀珮锛屼紭鍏堜笌.id_table 杩涜鍖归厤 .id_table = &beep_idtable}; static int beep_driver_init(void) { //1.鎴戜滑鐪嬮┍鍔ㄦ枃浠惰浠?init 鍑芥暟寮€濮嬬湅 int ret = 0; //2. 鍦?init 鍑芥暟閲岄潰娉ㄥ唽浜?platform_driver ret = platform_driver_register(&beep_driver); if (ret < 0) { printk("platform_driver_register error \n"); } printk("platform_driver_register ok \n"); return 0; } static void beep_driver_exit(void) { free_irq(irq, NULL); //tasklet_kill(&key_test); platform_driver_unregister(&beep_driver); printk("gooodbye! \n"); } module_init(beep_driver_init); module_exit(beep_driver_exit); MODULE_LICENSE("GPL"); 运行效果:
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。