下面的这个驱动文件at91_keyled.c在Atmel提供的linux-at91-linux4sam_5.3下实现了按键控制LED的亮灭过程,通过这个简单的驱动描述了基于DTS的驱动开发模型以及Linux内核里的GPIO相关的操作函数。 1 /************** ...
下面的这个驱动文件at91_keyled.c在Atmel提供的linux-at91-linux4sam_5.3下实现了按键控制LED的亮灭过程,通过这个简单的驱动描述了基于DTS的驱动开发模型以及Linux内核里的GPIO相关的操作函数。
1 /********************************************************************************* 2 * Copyright: (C) 2016 Guo Wenxue<guowenxue@gmail.com> 3 * All rights reserved. 4 * 5 * Filename: at91_keyled.c 6 * Description: This is a sample driver for GPIO operation with DTS linux on at91, 7 * which willl turn led on when a button pressed. 8 * 9 * Version: 1.0.0(2016-6-29~) 10 * Author: Guo Wenxue <guowenxue@gmail.com> 11 * ChangeLog: 1, Release initial version on "Wed Jun 29 12:00:44 CST 2016" 12 * 13 * 14 * DTS Changes: 15 * add keyleds support in arch/arm/boot/dts/at91sam9x5cm.dtsi 16 * 17 * keyleds{ 18 * compatible = "key-leds"; 19 * gpios = <&pioB 18 GPIO_ACTIVE_LOW priv->pin_key=of_get_gpio(pdev->dev.of_node, 0); 20 * &pioB 16 GPIO_ACTIVE_LOW>; priv->pin_key=of_get_gpio(pdev->dev.of_node, 1); 21 * status = "okay"; 22 * } 23 * 24 * 1wire_cm { 25 * ... ... 26 * ... ... 27 * } 28 * 29 ********************************************************************************/ 30 31 #include <linux/module.h> 32 #include <linux/moduleparam.h> 33 #include <linux/platform_device.h> 34 35 #include <linux/of.h> 36 #include <linux/of_device.h> 37 #include <linux/of_gpio.h> 38 #include <linux/delay.h> 39 #include <linux/gpio.h> 40 #include <linux/interrupt.h> 41 42 typedef struct keyled_priv_s 43 { 44 int pin_key; 45 int pin_led; 46 int led_status; 47 } keyled_priv_t; /*--- end of struct keyled_priv_s ---*/ 48 49 50 static const struct of_device_id of_key_leds_match[] = { 51 { .compatible = "key-leds", }, 52 {}, 53 }; 54 MODULE_DEVICE_TABLE(of, of_key_leds_match); 55 56 57 static irqreturn_t key_detect_interrupt(int irq, void *dev_id) 58 { 59 keyled_priv_t *priv = (keyled_priv_t *)dev_id; 60 61 priv->led_status ^= 1; 62 gpio_set_value(priv->pin_led, priv->led_status); 63 64 return IRQ_HANDLED; 65 } 66 67 68 static int at91_keyled_probe(struct platform_device *pdev) 69 { 70 int res; 71 keyled_priv_t *priv; 72 73 printk(KERN_INFO "at91_keyled driver probe\n"); 74 75 if( 2 != of_gpio_count(pdev->dev.of_node) ) 76 { 77 printk(KERN_ERR "keyled pins definition in dts invalid\n"); 78 return -EINVAL; 79 } 80 81 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 82 if(!priv) 83 return -ENOMEM; 84 85 platform_set_drvdata(pdev, priv); 86 87 priv->pin_key=of_get_gpio(pdev->dev.of_node, 0); 88 priv->pin_led=of_get_gpio(pdev->dev.of_node, 1); 89 90 if( gpio_is_valid(priv->pin_key) ) 91 { 92 if( (res=devm_gpio_request(&pdev->dev, priv->pin_key, "keyled_key")) < 0 ) 93 { 94 dev_err(&pdev->dev, "can't request key gpio %d\n", priv->pin_key); 95 return res; 96 } 97 dev_info(&pdev->dev, "request key gpio %d ok\n", priv->pin_key); 98 99 if( (res=gpio_direction_input(priv->pin_key)) < 0 )100 {101 dev_err(&pdev->dev, "can't request input direction key gpio %d\n", priv->pin_key);102 return res;103 }104 dev_info(&pdev->dev, "request input direction key gpio %d ok\n", priv->pin_key);105 106 printk(KERN_INFO "Key gpio current status: %d\n", gpio_get_value(priv->pin_key));107 108 res = request_irq( gpio_to_irq(priv->pin_key), key_detect_interrupt, IRQF_TRIGGER_FALLING, "keyled", priv);109 if( res )110 {111 dev_err(&pdev->dev, "can't request IRQ<%d> for key gpio %d\n", gpio_to_irq(priv->pin_key), priv->pin_key);112 return -EBUSY;113 }114 dev_info(&pdev->dev, "request IRQ<%d> for key gpio %d ok\n", gpio_to_irq(priv->pin_key), priv->pin_key);115 }116 117 if( gpio_is_valid(priv->pin_led) )118 {119 if( (res=devm_gpio_request(&pdev->dev, priv->pin_led, "keyled_led")) < 0 )120 {121 dev_err(&pdev->dev, "can't request key gpio %d\n", priv->pin_led);122 return res;123 }124 125 if( (res=gpio_direction_output(priv->pin_led, 0)) < 0 )126 {127 dev_err(&pdev->dev, "can't request output direction key gpio %d\n", priv->pin_led);128 return res;129 }130 }131 132 return 0;133 }134 135 static int at91_keyled_remove(struct platform_device *pdev)136 {137 keyled_priv_t *priv = platform_get_drvdata(pdev);138 139 printk(KERN_INFO "at91_keyled driver remove\n");140 141 devm_gpio_free(&pdev->dev, priv->pin_led);142 devm_gpio_free(&pdev->dev, priv->pin_key);143 144 free_irq(gpio_to_irq(priv->pin_key), priv);145 146 devm_kfree(&pdev->dev, priv);147 148 return 0;149 }150 151 static struct platform_driver at91_keyled_driver = {152 .probe = at91_keyled_probe,153 .remove = at91_keyled_remove,154 .driver = {155 .name = "key-leds",156 .of_match_table = of_key_leds_match,157 },158 };159 160 module_platform_driver(at91_keyled_driver);161 162 MODULE_AUTHOR("guowenxue <guowenxue@gmail.com>");163 MODULE_DESCRIPTION("AT91 Linux DTS GPIO driver for Key and LED");164 MODULE_LICENSE("GPL");165 MODULE_ALIAS("platform:key-leds");
海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com
原标题:at91 linux 4.1.0下dts驱动编程模型
关键词:linux
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。