AT91 GPIO驱动源代码

工作需要,编写GPIO驱动,已经测试通过。虽然现在看起来很简单,但是我刚出道,当时是绞尽了脑汁,分享一下给一些Linux刚上道的兄弟,让大家少走点弯路。注意,cmd=2在Linux-3.6.9中,ioctl不可以用此值,经核查此cmd已经被内核占用。我在这里也走过弯路,希望兄弟们不要再走了。

/*

@ lanjun

@2013.12.10

@cpu : AT91SAM9G45  

@kerbel:linux-3.6.9

@gpio_c.c

*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/init.h>
 
#include <linux/miscdevice.h>
#include <mach/gpio.h>
#include <asm/uaccess.h> 
#include "./GpioCaseCode.h"

#define DEVICE_NAME "gpio_c"

static long gpio_c_ioctl(struct file *filp, unsigned int cmd,
  unsigned long arg)
{
 long val=0; 

 printk();
 switch (cmd)
 {
    case INPUT_PB21:
        {
        val=at91_get_gpio_value(AT91_PIN_PB21);
  put_user(val,(long *)arg);
  break;    
        }
    case INPUT_PB22:
        {
        val=at91_get_gpio_value(AT91_PIN_PB22);
  put_user(val,(long *)arg);
  break;    
        }
    case INPUT_PB23:
        {
        val= at91_get_gpio_value(AT91_PIN_PB23);
  put_user(val,(long *)arg);
  break;    
        }
    case INPUT_PB24:
        {
        val=at91_get_gpio_value(AT91_PIN_PB24);
  put_user(val,(long *)arg);
  break;    
        }
    case INPUT_PB25:
        {
        val=at91_get_gpio_value(AT91_PIN_PB25);
  put_user(val,(long *)arg);
  break;    
        }
    case INPUT_PB26:
        {
        val= at91_get_gpio_value(AT91_PIN_PB26);
  put_user(val,(long *)arg);
  break;    
        }
   /* case INPUT_PB27:
        {
        val= at91_get_gpio_value(AT91_PIN_PB27);
  put_user(val,(long *)arg);
  break;    
        }*/

    case OUTPUT_PB20:
        {
        at91_set_gpio_value(AT91_PIN_PB20,arg);  
  break;    
        }

 case OUTPUT_PB28:
        {
        at91_set_gpio_value(AT91_PIN_PB28,arg);  
  break;    
        }
 case OUTPUT_PB29:
        {
        at91_set_gpio_value(AT91_PIN_PB29,arg);  
  break;    
        }
 case OUTPUT_PB30:
     {
     at91_set_gpio_value(AT91_PIN_PB30,arg);  
  break;    
     }
 case OUTPUT_PB31:
     {
     at91_set_gpio_value(AT91_PIN_PB31,arg);  
  break;    
     }
 case OUTPUT_PC24:
     {
     at91_set_gpio_value(AT91_PIN_PC24,arg);  
  break;    
     }
 case OUTPUT_PC22:
     {
     at91_set_gpio_value(AT91_PIN_PC22,arg);  
  break;    
     }
 case OUTPUT_PC20:
     {
     at91_set_gpio_value(AT91_PIN_PC20,arg);  
  break;    
     }
 case OUTPUT_PC18:
     {
     at91_set_gpio_value(AT91_PIN_PC18,arg);  
  break;    
     }
 case OUTPUT_PC16:
     {
     at91_set_gpio_value(AT91_PIN_PC16,arg);  
  break;    
     }
  
  
    default: return -ENOTTY;
    }

    return 0;
}

static int gpio_c_open(struct inode *inode, struct file *file)
{
 printk("Now device open successfully !\n");
 return 0;
}

static struct file_operations gpio_c_dev_fops = {
 .owner   = THIS_MODULE,
 .unlocked_ioctl = gpio_c_ioctl,
 .open    = gpio_c_open,
};

static struct miscdevice gpio_c_dev = {
 .minor   = MISC_DYNAMIC_MINOR,
 .name   = DEVICE_NAME,
 .fops   = &gpio_c_dev_fops,
};

static int __init gpio_c_dev_init(void) {
 int ret=0;

 ret = misc_register(&gpio_c_dev);
 //use_pullup inside  set 1,otherwise clear 0
 at91_set_gpio_input(AT91_PIN_PB21, 0);
 at91_set_gpio_input(AT91_PIN_PB22, 0);
 at91_set_gpio_input(AT91_PIN_PB23, 0);
 at91_set_gpio_input(AT91_PIN_PB24, 0);
 at91_set_gpio_input(AT91_PIN_PB25, 0);
 at91_set_gpio_input(AT91_PIN_PB26, 0);
 at91_set_gpio_input(AT91_PIN_PB27, 0);
 //at91_set_gpio_output(unsigned pin, int value)
 at91_set_gpio_output(AT91_PIN_PB20, LOW);
 at91_set_gpio_output(AT91_PIN_PB28, LOW);
 at91_set_gpio_output(AT91_PIN_PB29, LOW);
 at91_set_gpio_output(AT91_PIN_PB30, LOW);
 at91_set_gpio_output(AT91_PIN_PB31, LOW);
 at91_set_gpio_output(AT91_PIN_PC24, LOW);
 at91_set_gpio_output(AT91_PIN_PC22, LOW);
 at91_set_gpio_output(AT91_PIN_PC20, LOW);
 at91_set_gpio_output(AT91_PIN_PC18, LOW);
 at91_set_gpio_output(AT91_PIN_PC16, LOW);

 printk(DEVICE_NAME"\tinitialized\n");

 return ret;
}

static void __exit gpio_c_dev_exit(void) {
 
 misc_deregister(&gpio_c_dev);
 
 printk(DEVICE_NAME"\t exit\n");
 
}

module_init(gpio_c_dev_init);
module_exit(gpio_c_dev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("lj_6@163.com");

 

 

/*

@ lanjun

@2013.12.10

@cpu : AT91SAM9G45

@GpioCaseCode.h

*/

#ifndef __GPIO_CASE_CODES_H__
#define __GPIO_CASE_CODES_H__
/*
addby lanjun  2013.11.10

ioctl(fd,CASE_CODES,arg) instruction:
1.CASE_CODES  can be defined as follows.
2.If CASE_CODE is output_class ,you need to give the arg to
tell driver  what you want to output: HIGH or LOW.
3.Corresponding  to each case, there is only one pin .
*/
//input pins CASE_CODES without pullup inside of CPU
#define INPUT_PB21 (1)
#define INPUT_PB22 (8)
#define INPUT_PB23 (3)
#define INPUT_PB24 (4)
#define INPUT_PB25 (5)
#define INPUT_PB26 (6)
//#define INPUT_PB27 (7)

 

//output pins CASE_CODES
#define OUTPUT_PB20 (10)
#define OUTPUT_PB28 (11)
#define OUTPUT_PB29 (12)
#define OUTPUT_PB30 (13)
#define OUTPUT_PB31 (14)
#define OUTPUT_PC24 (15)
#define OUTPUT_PC22 (16)
#define OUTPUT_PC20 (17)
#define OUTPUT_PC18 (18)
#define OUTPUT_PC16 (19)
#define HIGH 1
#define LOW  0
#endif

 

 

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值