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

来源:互联网 发布:淘宝官方买家秀在哪里 编辑:程序博客网 时间:2024/04/30 03:31

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");
0 0
原创粉丝点击