am335 gpio

#include <linux/init.h>
#include <linux/module.h>
#include <linux/leds.h>
#include <linux/io.h>
#include <linux/semaphore.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <mach/gpio.h>
#include <plat/mux.h>
#include <linux/gpio.h>
#include <linux/slab.h>


/************************
gpmc_ad8.gpio0_22
gpmc_ad9.gpio0_23
gpmc_ad10.gpio0_26
gpmc_ad11.gpio0_27
gpmc_ad12.gpio1_12
gpmc_ad13.gpio1_13
gpmc_ad14.gpio1_14
gpmc_ad15.gpio1_15      

AM335X_GPMC_AD12---821
AM335X_GPMC_AD14---120
AM335X_GPMC_AD15---mc8635                                              
************************/

#define GPIO_IOC_MAGIC					'G'
#define IOCTL_GPIO_SETOUTPUT				_IOW(GPIO_IOC_MAGIC, 0, int)                   
#define IOCTL_GPIO_SETINPUT				_IOW(GPIO_IOC_MAGIC, 1, int)
#define IOCTL_GPIO_SETVALUE				_IOW(GPIO_IOC_MAGIC, 2, int) 
#define IOCTL_GPIO_GETVALUE				_IOR(GPIO_IOC_MAGIC, 3, int)
#define GPIO_IOC_MAXNR					3

#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))

struct am335x_gpio_arg{
        int pin;
        int data;
};
 
struct am335x_gpio_node{
        int pin;
        struct am335x_gpio_node *next;
};

static int gpio_major = 0;
static int gpio_minor = 0;
static struct class *gpio_class;
static struct class_device *class_dev;
static struct cdev gpio_cdev;
static struct am335x_gpio_node *head;

static int is_required(int pinnum)
{	
	struct am335x_gpio_node *pnode = head->next;
	struct am335x_gpio_node *rnode = head;

	while(pnode != NULL)
	{
		if(pnode->pin == pinnum)
			return 0;
		else
		{
			rnode = pnode;
			pnode = pnode->next;
		}
	}
	printk("New GPIO Register at pin num %d\n",pinnum);
	pnode = (struct am335x_gpio_node *)kmalloc(sizeof(struct am335x_gpio_node), GFP_KERNEL);
	if(pnode != NULL)
	{
		rnode->next = pnode;
		pnode->pin = pinnum;
		pnode->next = NULL;
	}
	else
		printk("Can't Kmalloc... register fail\n");
	
	return 1;

}

static int gpio_open(struct inode *inode,struct file *filp)
{
	//is_required(GPIO_TO_PIN(0,22));	
	//is_required(GPIO_TO_PIN(0,23));
	//is_required(GPIO_TO_PIN(0,26));	
	//is_required(GPIO_TO_PIN(0,27));	
	//is_required(GPIO_TO_PIN(1,12));	
	//is_required(GPIO_TO_PIN(1,13));
	//is_required(GPIO_TO_PIN(1,14));	
	//is_required(GPIO_TO_PIN(1,15));		
	return 0;
}

static int gpio_release(struct inode *inode,struct file *filp)
{
	//struct am335x_gpio_node *pnode = head->next;
	//struct am335x_gpio_node *rnode = NULL;
	//while(pnode != NULL )
	//    {
	//	rnode = pnode->next;
	//	kfree(pnode);
	//	pnode = rnode;
	//    }
	//kfree(head); //freed by exit function
	return 0;
}


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

	
	struct am335x_gpio_arg *parg = (struct am335x_gpio_arg *)arg;  
	

	if(is_required(parg->pin))
	{
		err = gpio_request(parg->pin, "am335x_gpio");
		if(err != 0)
		{	
			printk("Can't request this gpio!\n");
			gpio_free(parg->pin);
		}				
	}
	switch (cmd) {
	case IOCTL_GPIO_SETOUTPUT:
			
			gpio_direction_output(parg->pin, parg->data);
		break;	
	case IOCTL_GPIO_SETINPUT:

			gpio_direction_input(parg->pin);
		break;
	case IOCTL_GPIO_SETVALUE:

			gpio_set_value(parg->pin, parg->data);
		break;
	case IOCTL_GPIO_GETVALUE:

			parg->data = gpio_get_value(parg->pin) ? 1 : 0;
		break;
	default :
			printk(KERN_WARNING "Unsuported Ioctl Cmd\n");
	}
	
	return 0;
	
}

struct file_operations gpio_fops = {
	.owner =    THIS_MODULE,
	.open =     gpio_open,
	.unlocked_ioctl =    gpio_ioctl,
	.release =  gpio_release,
};


static int __init am335x_gpio_init(void)
{
	int result;
	dev_t dev = 0;


	result = alloc_chrdev_region(&dev, gpio_minor, 1,"am335x_gpio_group");
	gpio_major = MAJOR(dev);
	if (result < 0) {
		printk(KERN_WARNING "Can't get major %d\n", gpio_major);
		return result;
	}
	printk("AM335X GPIO GROUP Driver Registered.\n");

	cdev_init(&gpio_cdev, &gpio_fops);
	gpio_cdev.owner = THIS_MODULE;
	gpio_cdev.ops = &gpio_fops;
	result = cdev_add (&gpio_cdev, dev, 1);

	gpio_class = class_create(THIS_MODULE, "am335x_gpio_group");
	if (IS_ERR(gpio_class)) {
        	printk(KERN_WARNING "Class_create faild\n");
		cdev_del(&gpio_cdev);
		unregister_chrdev_region(dev, 0);
		return result;
	}
	class_dev = device_create(gpio_class,NULL,dev,0,"am335x_gpio_group");

	head = (struct am335x_gpio_node *)kmalloc(sizeof(struct am335x_gpio_node), GFP_KERNEL);
	if(head == NULL)
	{
		return -1;
	}
	else  
    {  
        head->pin = 0;  
        head->next = NULL;    
    }  
	return 0;
}

static void __exit am335x_gpio_exit(void)
{
	dev_t dev = 0;
	struct am335x_gpio_node *pnode = head->next;
	struct am335x_gpio_node *rnode = NULL;
	
	while(pnode != NULL )
    {
		rnode = pnode->next;
        kfree(pnode);
        pnode = rnode;
    }
	kfree(head);
	
	dev = MKDEV(gpio_major, gpio_minor);

	class_unregister(class_dev);
	class_destroy(gpio_class);
	unregister_chrdev_region(dev, 0); 
	cdev_del(&gpio_cdev);
}


module_init(am335x_gpio_init);
module_exit(am335x_gpio_exit);


MODULE_DESCRIPTION("Driver for AM335X GPIO");
MODULE_AUTHOR("[email protected]");
MODULE_LICENSE("GPL");




#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
#include <linux/ioctl.h>


/************************
gpmc_ad8.gpio0_22
gpmc_ad9.gpio0_23
gpmc_ad10.gpio0_26
gpmc_ad11.gpio0_27
gpmc_ad12.gpio1_12
gpmc_ad13.gpio1_13
gpmc_ad14.gpio1_14
gpmc_ad15.gpio1_15      

AM335X_GPMC_AD12---821
AM335X_GPMC_AD14---120
AM335X_GPMC_AD15---mc8635                                              
************************/


#define DEV_GPIO "/dev/am335x_gpio_group"

#define GPIO_IOC_MAGIC   'G'
#define IOCTL_GPIO_SETOUTPUT              _IOW(GPIO_IOC_MAGIC, 0, int)       
//#define IOCTL_GPIO_SETINPUT               _IOW(GPIO_IOC_MAGIC, 1, int)
//#define IOCTL_GPIO_SETVALUE               _IOW(GPIO_IOC_MAGIC, 2, int) 
//#define IOCTL_GPIO_GETVALUE    		  _IOR(GPIO_IOC_MAGIC, 3, int)

#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))


typedef struct {
        int pin;
        int data;
}am335x_gpio_arg;


int main(int argc, void *argv[])
{
	am335x_gpio_arg arg;
	int fd = -1;
	int i = 0, group = 0, num = 0;

	fd = open(DEV_GPIO, O_RDWR);
	if (fd < 0) {
		printf("Error device open fail! %d\n", fd);
		return -1;
	}
	arg.data = 1;// 1- set gpio to high level 0- low level
	arg.pin = GPIO_TO_PIN(1, 12);//gpmc_ad8.gpio0_22 ,  at top region of this file , gpio  list show.
	ioctl(fd, IOCTL_GPIO_SETOUTPUT, &arg);
	arg.pin = GPIO_TO_PIN(1, 14);	
	ioctl(fd, IOCTL_GPIO_SETOUTPUT, &arg);
	arg.pin = GPIO_TO_PIN(1, 15);	
	ioctl(fd, IOCTL_GPIO_SETOUTPUT, &arg);

	printf("set all 1\n");
	sleep(5);
	printf("sleep.\n");
	sleep(5);
	printf("sleep.\n");
	sleep(5);
	printf("sleep.\n");

	arg.data = 0;// 1- set gpio to high level 0- low level
	arg.pin = GPIO_TO_PIN(1, 12);//gpmc_ad8.gpio0_22 ,  at top region of this file , gpio  list show.
	ioctl(fd, IOCTL_GPIO_SETOUTPUT, &arg);
	arg.pin = GPIO_TO_PIN(1, 14);	
	ioctl(fd, IOCTL_GPIO_SETOUTPUT, &arg);
	arg.pin = GPIO_TO_PIN(1, 15);	
	ioctl(fd, IOCTL_GPIO_SETOUTPUT, &arg);

	printf("set all 0\n");

	close(fd);
	printf("close file\n");
	return 0;
}






猜你喜欢

转载自blog.csdn.net/liuxizhen2009/article/details/87738265