Transferred from: http://blog.chinaunix.net/uid-29165999-id-4296162.html
#define GPIO_MAJOR//MAJOR device NO.
#define GPIO_MINOR 0//MINOR device NO.
#define DEVICE_NAME "Gpios"
#define SET_OUTPUT_LOW 0
#define SET_OUTPUT_HIGH 1
#define GET_VALUE 2
#define SET_INPUT 3
static struct class *gpio_class;
static struct Gpio gpio_array[] =
{
{gpio_to_pin (0, 0), Gpiof_out_init_low, "rtu_wdi_signal"},
{gpio_to_pin (0, 1), Gpiof_out_init_high, "Rtu_plc_bak_io1"},
};
static int Gpio_open (struct inode *inode,struct file *file)
{
PRINTK (kern_warning "Gpio open success!\n");
return 0;
}
static int gpio_release (struct inode *inode, struct file *filp)
{
PRINTK (kern_alert "Device gpio released\n");
return 0;
}
Static long gpio_ioctl (struct file *file,unsigned int cmd,unsigned long Gpio)
{
int i;
unsigned long gpio_nu m = (gpio/100) *16+gpio%100;
for (i = 0; i < array_size (Gpio_array); i++) {
if (Gpio_array[i].gpio = = gpio_num)
goto Valid_gpio;
}
Return-1;
Valid_gpio:
switch (CMD)//cmd represents the application's incoming Gpio action
{
Case set_output_low://0
{
Gpio_direction_ Output (gpio_num, 0);
break;
}
Case SET_OUTPUT_HIGH://1
{
Gpio_direction_output (gpio_num, 1);
break;
}
Case GET_VALUE://2
{
return gpio_get_value (Gpio_num);
}
Case SET_INPUT://3
{
Gpio_direction_input (gpio_num);
break;
}
Default:
{
Printk (kern_emerg "GPIO command mistake!!! \ n ");
break;
}
}
return 0;
}
Static const struct File_operations Gpio_fops =
{
. Owner = This_module,
. Open = Gpio_open,
. Releas E = Gpio_release,
. Unlocked_ioctl = Gpio_ioctl,
};
Driver Load function
static int __init gpio_init (void)
{
int ret;
Register some of the columns Gpio
ret = Gpio_request_array (Gpio_array, Array_size (Gpio_array));
if (Ret < 0)
{
PRINTK (Kern_emerg "GPIO request failed\n");
Goto request_failed;
}
const char *name = device_name;
dev_t My_dev_no;
struct Cdev *gpio_cdev;
Assigning Cdev Structures
Gpio_cdev = Cdev_alloc ();
if (Gpio_cdev = = NULL)
{
PRINTK (Kern_emerg "Cannot alloc cdev\n");
Goto request_failed;
}
Initialize the CDEV structure body
Cdev_init (Gpio_cdev,&gpio_fops);
gpio_cdev->owner=this_module;
int result=alloc_chrdev_region (&my_dev_no,0,1,device_name); Dynamically Assign Device numbers
if (Result < 0)
{
PRINTK (Kern_emerg "alloc_chrdev_region failed\n");
Goto request_failed;
}
Kobject_set_name (&cdev->kobj, "%s", name);
Ret=cdev_add (gpio_cdev,my_dev_no,1);
if (Ret < 0)
{
PRINTK (Kern_emerg "GPIO register failed\n");
Goto request_failed;
}
Create a class under the Sysfs file system
Gpio_class = Class_create (This_module, device_name);
Creating a Device node in/dev
Device_create (Gpio_class, NULL, MY_DEV_NO, NULL, device_name);
return ret;
Request_failed:
Gpio_free_array (Gpio_array, Array_size (Gpio_array));
return ret;
}
static void __exit gpio_exit (void)
{
Device_destroy (Gpio_class, MKDEV (Gpio_major, Gpio_minor));
Class_unregister (Gpio_class);
Unregister_chrdev (Gpio_major, device_name);
}
Module_init (Gpio_init);
Module_exit (Gpio_exit);
Module_license ("GPL");
Creating GPIO nodes in Linux