穿拖鞋的小猫 https://bbs.21ic.com/?267654 [收藏] [复制] [RSS]

日志

About GPIO driver

已有 1054 次阅读2008-10-11 14:38 |系统分类:ARM

/*
*2008-1-15
This is my first linux driver
*/


#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/poll.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/miscdevice.h>


#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>


#include "hi_gpio.h"


#define DEVICE_NAME "led_gpio"


static unsigned int LED_MAJOR = 20;
unsigned int led_Major;



#define led_on_cmd  0
#define led_off_cmd  1


#define relay_open_cmd 3
#define relay_close_cmd 4
#define center_ch_cmd  5
#define system_ch_cmd  6



#define input     0 /*用于指示IO口是输入还是输出*/
#define output    1 /*用于指示IO口是输入还是输出*/
 
#define led_portnum   1 /*led 灯的组号*/
#define relay_portnum  0 /*继电器的切换所用的IO口组号*/
#define jump_portnum  1 /*2K,3K,中心   跳线选择所用的组号*/



#define data_in   0
#define data_out  1
#define busy   2
#define setip   3
#define system_ch 4
#define center_ch 5



#define audio   6
#define video   7
#define com485  1


 


static int gpio_init(void)
{
 unsigned int temp = 0;


 gpio_dirsetbit(led_portnum, data_in, output);
 gpio_dirsetbit(led_portnum, data_out, output);
 gpio_dirsetbit(led_portnum, busy, output);
 gpio_dirsetbit(led_portnum, setip, output);
 gpio_dirsetbit(led_portnum, setip, output);


 


 gpio_writebit(led_portnum, data_in, 1);
 gpio_writebit(led_portnum, data_out, 1);
 gpio_writebit(led_portnum, busy, 1);
 gpio_writebit(led_portnum, setip, 1);


 
 gpio_dirsetbit(relay_portnum, audio, output);
 gpio_dirsetbit(relay_portnum, video, output);
 gpio_dirsetbit(relay_portnum, com485, output);
 
 gpio_writebit(relay_portnum, audio, 0);
 gpio_writebit(relay_portnum, video, 0);
 gpio_writebit(relay_portnum, com485, 0);


 gpio_dirsetbit(jump_portnum, system_ch, input);/*2K,3K系统的选择*/
 gpio_dirsetbit(jump_portnum, center_ch, input);/*是否接中心机的选择*/
 return 0;
}


/*
* open LED
* input:port number of need open
*/
int led_gpio_on(unsigned int portnum ,unsigned int bitx)
{
 int temp;
 
 //设置该GPIO为输出
// temp = gpio_dirsetbit(portnum, bitx, output);
 //使该GPIO输出为‘0’,点亮LED
 temp = gpio_writebit(portnum, bitx, 0);
 return 0;
}



/*
* close LED
* input:port number
*/
int led_gpio_off(unsigned int portnum ,unsigned int bitx)
{
 //设置该GPIO为输出
// gpio_dirsetbit(portnum, bitx, output);
 //使该GPIO输出为‘1’,熄灭LED
 gpio_writebit(portnum, bitx, 1);
 return 0;
}


/*
*
*/
int relay_open(unsigned int portnum, unsigned int bitx)
{
 int temp;
 
 //设置该GPIO为输出
// temp = gpio_dirsetbit(portnum, bitx, output);
 //使继电器吸合
 printk("relay_open portnum:%d,bitx:%d\n",portnum,bitx);
 temp = gpio_writebit(portnum, bitx, 0);
 return 0;
}


/*
*
*/
int relay_close(unsigned int portnum, unsigned int bitx)
{
 //设置该GPIO为输出
// gpio_dirsetbit(portnum, bitx, output);
 //释放继电器
 printk("relay_close portnum:%d,bitx:%d\n",portnum,bitx);
 gpio_writebit(portnum, bitx, 1);
 return 0;
}



/*
*arg是端口信息:bit0~bit7表示位号;bit8~bit15表示端口号
*例如:P1_7    arg = 0x00000107
*/
int led_gpio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

 unsigned int IO_num;
 unsigned int portnum;
 unsigned int bitx,ret;
 
 printk("LED_GPIO)IOCTL cmd=%d\n",cmd);
 printk("LED_GPIO)IOCTL arg=%ld\n",arg);
 IO_num = arg;
 portnum = IO_num >> 8;  
 bitx = IO_num & 0xff;
 
 switch(cmd)
 {
  case led_on_cmd:
   led_gpio_on(portnum, bitx);
   
   break;
  
  case led_off_cmd:
   led_gpio_off(portnum, bitx);
   
   break;
   
  case relay_open_cmd:
   relay_open(portnum, bitx);
   
   break;
   
  case relay_close_cmd:
   relay_close(portnum, bitx);
   
   break;
  case center_ch_cmd:
   gpio_readbit(jump_portnum, center_ch, &ret);
   break;
   
  case system_ch_cmd:
   gpio_readbit(jump_portnum, system_ch, &ret);
   break;
   
  default:
   break;
 }
 return ret;
}


int led_gpio_open(struct inode *inode,struct file *filp)
{
// init_timer(&led_timer);
// led_timer. = led_timer_handler;
 printk("********LED_GPIO_OPEN*****\n");
 
 return 0;
}


int led_gpio_release(struct inode *inode,struct file *filp)
{
 return 0;
}


struct file_operations led_gpio_fops = {
 .owner  = THIS_MODULE,
 .open  = led_gpio_open,
 .ioctl  = led_gpio_ioctl,
 .release  = led_gpio_release,
 };
 
int __init led_gpio_init(void)
{
 int ret;
 
 ret = register_chrdev(0,DEVICE_NAME,&led_gpio_fops);
 
 if(ret<0)
 {
  printk(KERN_ERR "led_gpio CAN'T GET MAJOR NUMBER \n");
  return ret;
 }
 led_Major = ret;
 printk(KERN_NOTICE "THE MAJOR: %d \n",led_Major);
#ifdef CONFIG_DEVFS_FS 
 devfs_mk_cdev(MKDEV(led_Major, 0), S_IFCHR|S_IRUGO|S_IWUSR, DEVICE_NAME);
#endif 
 gpio_remap();
 //relay_close(0,7); /*此配置为输出 */
 gpio_init();
 return 0;
}


void __exit led_gpio_exit(void)
{
 gpio_unmap();
 unregister_chrdev(led_Major,DEVICE_NAME);
 printk(KERN_NOTICE "FREE END");
 
}


module_init(led_gpio_init);
module_exit(led_gpio_exit);
MODULE_LICENSE("GPL");


/*
*其它驱动程序可直接调用
*/
EXPORT_SYMBOL(led_gpio_on);
EXPORT_SYMBOL(led_gpio_off);


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)