|
/*
*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);