您的位置:首页 > 运维架构 > Linux

at91 linux 4.1.0下dts驱动编程模型,at914.1.0

2016-11-11 13:43 176 查看


at91 linux 4.1.0下dts驱动编程模型,at914.1.0

下面的这个驱动文件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");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐