TI am3352 gpio 驱动

最近用到了am3352 linux gpio 的驱动贴出来一起共勉。
有瑕疵请留言哦。
#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include "gpio.h"



struct gpio_info {

	u32  	 	   pin;

	char 	 	   pin_name[20];

	struct miscdevice *pmiscdev;

};



static struct gpio_info *gpio_info_file[255];



static struct gpio_info *all_gpios_info;



static struct gpio_info all_gpios_info_am3352[] ={

	{41,     "touct",        NULL},

        {40,     "voice",         NULL},

	{0,	 "",          NULL},   //the end

};



static int gpio_open(struct inode *inode, struct file *filp);

static int  gpio_release(struct inode *inode, struct file *filp);

ssize_t gpio_write(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos);

static long gpio_ioctl(struct file *flip, unsigned command, unsigned long arg);

static int gpio_init(void);

static void gpio_exit(void);



static int gpio_open(struct inode *inode, struct file *filp)

{

	

	struct gpio_info *gpio_info_tmp;

	u32 minor = iminor(inode);

	gpio_info_tmp = kmalloc(sizeof(struct gpio_info), GFP_KERNEL);

	gpio_info_tmp = gpio_info_file[minor];

	filp->private_data = gpio_info_tmp ;		

	gpio_free(gpio_info_tmp->pin);

	printk("gpio num= %d\n",gpio_info_tmp->pin);

	if (gpio_request(gpio_info_tmp->pin, gpio_info_tmp->pin_name)) {

		printk("request %s gpio faile \n", gpio_info_tmp->pin_name);

		return -1;

	}

	

	return 0;

}



static int  gpio_release(struct inode *inode, struct file *filp)

{

	

	struct gpio_info *gpio_info_tmp = (struct gpio_info *)filp->private_data;

	gpio_free(gpio_info_tmp->pin);

	return 0;

}





ssize_t gpio_write(struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)

{

	struct gpio_info *gpio_info_tmp = (struct gpio_info *)filp->private_data;

	char data[2];



	printk("make: %s \n", gpio_info_tmp->pin_name);

	if(!copy_from_user(data, buf, 2))

	{

		data[0] = data[0] - '0';



		if (data[0] == 1 || data[0] == 0) {

		        gpio_direction_output(gpio_info_tmp->pin, data[0]);

		}

		return count;

	}

	else

	{

		return  -1;

	}

}





static ssize_t gpio_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)

{

		

	struct gpio_info *gpio_info_tmp = (struct gpio_info *)file->private_data;

	char data[2];



	gpio_direction_input(gpio_info_tmp->pin);

	data[0] = gpio_get_value(gpio_info_tmp->pin);

	data[0] = data[0] ? 1 : 0;



	data[0] = data[0] + '0';

	data[1] = '\n';

	if(!copy_to_user(buf,data,2))

	{

		return 0;

	}

	else

	{

		return -1;

	}

}

static long gpio_ioctl(struct file *flip, unsigned command, unsigned long arg)

{

	//printk("ioctl \n");	

	struct gpio_info *gpio_info_tmp = (struct gpio_info *)flip->private_data;

	int  data = 0;

	//printk("cmd = %d \n",command);	

	switch (command) {

	case SET_GPIO_HIGHT: 

		gpio_direction_output(gpio_info_tmp->pin, 1);

		break;

	

	case SET_GPIO_LOW:

		gpio_direction_output(gpio_info_tmp->pin, 0);

		break;



	case GET_GPIO_VALUE:

		gpio_direction_input(gpio_info_tmp->pin);

		data = gpio_get_value(gpio_info_tmp->pin);

		data = data ? 1 : 0;

		//copy_to_user((void *)arg, (void *)(&data), sizeof(int));

		if(copy_to_user((void *)arg, (void *)(&data), sizeof(int)))

		{

			return -1;

		}

			

		break;

	default:

		printk("cmd error \n");	

		return -1;

	}



	return 0;

	

}





static struct file_operations gpio_fops={

	.owner		= THIS_MODULE,

	.unlocked_ioctl = gpio_ioctl,

	.open 		= gpio_open,

	.write		= gpio_write,

	.read		= gpio_read,

	.release	= gpio_release,

};



static int __init gpio_init(void)

{

	

	int i = 0;

	int ret = 0;

	all_gpios_info = all_gpios_info_am3352;

	

	for (i = 0; all_gpios_info[i].pin != 0; i++) {

		all_gpios_info[i].pmiscdev = kmalloc(sizeof(struct miscdevice), GFP_KERNEL);

		if (all_gpios_info[i].pmiscdev == NULL) {

			printk("unable to malloc memory \n");

			return -1;

		}



		

		memset(all_gpios_info[i].pmiscdev, 0, sizeof(struct miscdevice));

		all_gpios_info[i].pmiscdev->name  = all_gpios_info[i].pin_name;

		all_gpios_info[i].pmiscdev->fops  = &gpio_fops;	

		all_gpios_info[i].pmiscdev->minor = MISC_DYNAMIC_MINOR;



		ret = misc_register(all_gpios_info[i].pmiscdev);

		if (ret) {

			printk("misc regist faile \n");

			return -1;

		}



		gpio_info_file[all_gpios_info[i].pmiscdev->minor] = &(all_gpios_info[i]);

		

		printk("build device i:%d dev:/dev/%s \n", i, all_gpios_info[i].pmiscdev->name);

	}

	return 0;

	

}



static void __exit gpio_exit(void)

{

	

	int i = 0;



	for (i = 0; all_gpios_info[i].pin != 0; i++) {

		misc_deregister(all_gpios_info[i].pmiscdev);

	}

	printk("gpio driver down.\n");

	

}



module_init(gpio_init);

module_exit(gpio_exit);



MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("liusongnian");

MODULE_DESCRIPTION("GPIO DRIVER FOR am3352");




你可能感兴趣的:(LINUX,ARM,C,语言)