21,597
社区成员
发帖
与我相关
我的任务
分享
#ifndef __GEO_DS_GPIO_H__
#define __GEO_DS_GPIO_H__
#include <linux/sched.h>
#include <linux/init.h>
/* PIN definitions */
#define GEO_DS_GPIO_MAGIC 's'
#define SWITCH_LED_ON _IOW( GEO_DS_GPIO_MAGIC, 0, int ))
#define GEO_DS_GPIO_MAXNR 1
/* PIN definitions */
#define PIN_LED_STAT AT91_PIN_PB30
#endif // __GEO_DS_GPIO_H__
#include <linux/init.h>
#include <linux/module.h> /* get MOD_DEC_USE_COUNT, not the version string */
#include <linux/moduleparam.h>
#include <linux/version.h> /* need it for conditionals in geoad.h */
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#include <asm/arch/gpio.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <asm/system.h> /* rmb(), wmb() */
#include <asm/io.h> /* inb(), outb() */
#include <asm/uaccess.h>
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_ssc.h>
#include "geo_ds_gpio.h" /* local definitions */
#define GPIO_NR_DEVS 1 /* device number */
int gpio_major = 105; /* major device number */
int gpio_nr_devs = GPIO_NR_DEVS; /* number of gpio control devices */
char gpio_name[16]; /* device name */
MODULE_AUTHOR( "Pengchy" );
MODULE_LICENSE( "GPL" );
int gpio_ioctl( struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg )
{
if( _IOC_TYPE(cmd) != GEO_DS_GPIO_MAGIC )
return -EINVAL;
if( _IOC_NR(cmd) >= GEO_DS_GPIO_MAXNR )
return -EINVAL;
switch( cmd )
{
case SWITCH_LED_ON:
at91_set_gpio_value( PIN_LED_STAT, arg ); break;
default:
return -ENOTTY;
}
return 0;
}
/*
* Open and close.
*/
int gpio_open( struct inode *inode, struct file *filp )
{
return 0;
}
int gpio_release( struct inode *inode, struct file *filp )
{
return 0;
}
/* for device gpio control */
static struct file_operations gpio_fops =
{
.owner = THIS_MODULE,
.open = gpio_open,
.release = gpio_release,
.ioctl = gpio_ioctl,
};
struct GPIO_DEVS
{
struct cdev cdev; /* Char device structure */
};
static struct GPIO_DEVS gpio_device;
static struct gpio_dev_info
{
char *name;
struct GPIO_DEVS *dev;
struct file_operations *fops;
} gpio_devs[] = {
{ "gpio_ctl", &gpio_device, &gpio_fops }
};
/*
* Set up the char_dev structure for this device.
*/
void gpio_setup_cdev( struct gpio_dev_info *devinfo, int index )
{
int err, devno = MKDEV( gpio_major, index );
struct GPIO_DEVS *dev = devinfo->dev;
/* Do the cdev stuff. */
cdev_init( &dev->cdev, devinfo->fops );
kobject_set_name( &dev->cdev.kobj, devinfo->name );
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = devinfo->fops;
err = cdev_add( &dev->cdev, devno, 1 );
/* Fail gracefully if need be */
if( err )
{
printk( KERN_NOTICE "Error %d adding %s\n", err, devinfo->name );
kobject_put( &dev->cdev.kobj );
}
else
printk( KERN_NOTICE "%s registered at %x\n", devinfo->name, devno );
}
static void init_hardware_pin()
{
at91_set_gpio_output( PIN_LED_STAT, 1 );
}
static int __init gpio_init( void )
{
int err = -1, i = 0;
dev_t devno = MKDEV( gpio_major, 0 );
memset( gpio_name, '\0', sizeof(gpio_name) );
sprintf( gpio_name, "%s", "gpio_ctl" );
/*
* Get a range of minor numbers to work with, asking for a dynamic
* major unless directed otherwise at load time.
*/
if( gpio_major )
err = register_chrdev_region( devno, gpio_nr_devs, gpio_name );
else
{
err = alloc_chrdev_region( &devno, 0, gpio_nr_devs, gpio_name );
gpio_major = MAJOR( devno );
}
if( err < 0 )
{
printk( KERN_WARNING "gpio: can't get major %d\n", gpio_major );
goto err001;
}
// Setup the geo devices.
for( i = 0; i < gpio_nr_devs; i++ )
gpio_setup_cdev( &gpio_devs[i], i );
init_hardware_pin();
printk( KERN_INFO "***************** gpio control driver started **************\n" );
return 0;
err001:
return err;
}
static void __exit gpio_exit( void )
{
int i = 0;
dev_t devno = MKDEV( gpio_major, 0 );
init_hardware_pin();
/* Clean up the static devs */
for( i = 0; i < gpio_nr_devs; i++ )
{
struct GPIO_DEVS *dev = gpio_devs[i].dev;
cdev_del( &dev->cdev );
}
unregister_chrdev_region( devno, gpio_nr_devs );
}
module_init( gpio_init );
module_exit( gpio_exit );