现版:echo 0 > /dev/gpio_3_D6
cat /dev/gpio_3_D6
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <asm/io.h>
#include <linux/platform_device.h>
#include <linux/version.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_address.h>
struct gpio_kuka_dev
{
struct cdev cdev;
struct device_node *nd;
struct device *device;
dev_t dev_id;
int major;
unsigned int gpio;
int gpio_enable_value;
};
static struct gpio_kuka_dev *gpio_kuka;
static struct class * gpio_kuka_class;
static int first_read = 1;
static int gpio_kuka_open(struct inode *inode, struct file *pfile)
{
int ret = 0;
struct gpio_kuka_dev * dev = container_of(inode->i_cdev, struct gpio_kuka_dev, cdev);
pfile->private_data = dev;
return ret;
}
static ssize_t gpio_kuka_read(struct file *pfile, char __user *buf, size_t size, loff_t *offset)
{
int ret = 0;
struct gpio_kuka_dev *p;
char level_str[3] = {0};
int level = 0;
p = pfile->private_data;
level = gpio_get_value(p->gpio);
sprintf(level_str,"%d\n",level);
ret = copy_to_user(buf, level_str, sizeof(level_str));
if(first_read)
{
first_read = 0;
return sizeof(level_str);
}
else
{
first_read = 1;
return 0;
}
}
static ssize_t gpio_kuka_write(struct file *pfile, const char __user *buf, size_t size, loff_t *offset)
{
int ret = 0;
struct gpio_kuka_dev *p;
char level_str[2] = {0};
int level = 0;
p = pfile->private_data;
if(size > 2)
{
printk("invalid param\n");
return -1;
}
ret = copy_from_user(&level_str, buf, size);
level = simple_strtol(level_str, NULL, 10);
if(level != 0 && level != 1)
{
printk("invalid param\n");
return -1;
}
gpio_set_value(p->gpio, level);
printk("gpio set value %d\n",level);
return size;
}
static struct file_operations gpio_kuka_fops = {
.owner = THIS_MODULE,
.open = gpio_kuka_open,
.read = gpio_kuka_read,
.write = gpio_kuka_write,
};
static struct of_device_id of_gpio_kuka_ids[] = {
{.compatible = "gpio_kuka"},
{ }
};
static int gpio_kuka_probe(struct platform_device *pdev)
{
int gpio;
enum of_gpio_flags flag;
gpio_kuka = devm_kzalloc(&pdev->dev,sizeof(struct gpio_kuka_dev), GFP_KERNEL);
if (!gpio_kuka) {
return -ENOMEM;
}
alloc_chrdev_region(&gpio_kuka->dev_id, 0, 1, pdev->name);
gpio_kuka->major = MAJOR(gpio_kuka->dev_id);
cdev_init(&gpio_kuka->cdev, &gpio_kuka_fops);
cdev_add(&gpio_kuka->cdev, gpio_kuka->dev_id, 1);
gpio_kuka_class = class_create(THIS_MODULE, pdev->name);
gpio_kuka->device = device_create(gpio_kuka_class, NULL, gpio_kuka->dev_id, NULL, pdev->name);
gpio_kuka->nd = pdev->dev.of_node;
gpio = of_get_named_gpio_flags(pdev->dev.of_node, "gpio_kuka", 0, &flag);
if (!gpio_is_valid(gpio)) {
printk("kuka-gpio: %d is invalid\n", gpio); return -ENODEV;
}
if (gpio_request(gpio, "gpio_kuka")) {
printk("gpio %d request failed!\n", gpio);
gpio_free(gpio);
return -ENODEV;
}
gpio_kuka->gpio = gpio;
gpio_kuka->gpio_enable_value = (flag == OF_GPIO_ACTIVE_LOW) ? 0:1;
gpio_direction_output(gpio_kuka->gpio, gpio_kuka->gpio_enable_value);
printk("kuka gpio putout\n");
gpio_kuka->device->gpio = gpio_kuka->gpio;
return 0;
}
static int gpio_kuka_remove(struct platform_device *pdev)
{
gpio_free(gpio_kuka->gpio);
cdev_del(&gpio_kuka->cdev);
unregister_chrdev_region(gpio_kuka->dev_id, 1);
devm_kfree(&pdev->dev, gpio_kuka);
return 0;
}
static struct platform_driver gpio_driver_kuka = {
.driver = {
.owner = THIS_MODULE,
.name = "gpio_kuka",
.of_match_table = of_match_ptr(of_gpio_kuka_ids),
},
.probe = gpio_kuka_probe,
.remove = gpio_kuka_remove,
};
module_platform_driver(gpio_driver_kuka);
MODULE_LICENSE("GPL");
原版:
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <asm/io.h>
#include <linux/platform_device.h>
#include <linux/version.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_address.h>
struct gpio_kuka_dev
{
struct cdev cdev;
struct device_node *nd;
struct device *device;
dev_t dev_id;
int major;
unsigned int gpio;
int gpio_enable_value;
};
static struct gpio_kuka_dev *gpio_kuka;
static struct class * gpio_kuka_class;
static int first_read = 1;
static int gpio_kuka_open(struct inode *inode, struct file *pfile)
{
int ret = 0;
struct gpio_kuka_dev * dev = container_of(inode->i_cdev, struct gpio_kuka_dev, cdev);
pfile->private_data = dev;
return ret;
}
static ssize_t gpio_kuka_read(struct file *pfile, char __user *buf, size_t size, loff_t *offset)
{
int ret = 0;
struct gpio_kuka_dev *p;
char level_str[3] = {0};
int level = 0;
p = pfile->private_data;
level = gpio_get_value(p->gpio);
sprintf(level_str,"%d\n",level);
ret = copy_to_user(buf, level_str, sizeof(level_str));
if(first_read)
{
first_read = 0;
return sizeof(level_str);
}
else
{
first_read = 1;
return 0;
}
}
static ssize_t gpio_kuka_write(struct file *pfile, const char __user *buf, size_t size, loff_t *offset)
{
int ret = 0;
struct gpio_kuka_dev *p;
char level_str[2] = {0};
int level = 0;
p = pfile->private_data;
if(size > 2)
{
printk("invalid param\n");
return -1;
}
ret = copy_from_user(&level_str, buf, size);
level = simple_strtol(level_str, NULL, 10);
if(level != 0 && level != 1)
{
printk("invalid param\n");
return -1;
}
gpio_set_value(p->gpio, level);
printk("gpio set value %d\n",level);
return size;
}
static struct file_operations gpio_kuka_fops = {
.owner = THIS_MODULE,
.open = gpio_kuka_open,
.read = gpio_kuka_read,
.write = gpio_kuka_write,
};
static struct of_device_id of_gpio_kuka_ids[] = {
{.compatible = "gpio_kuka"},
{ }
};
static int gpio_kuka_probe(struct platform_device *pdev)
{
int gpio;
enum of_gpio_flags flag;
struct device_node *kuka_gpio_node = pdev->dev.of_node;
gpio_kuka = devm_kzalloc(&pdev->dev,sizeof(struct gpio_kuka_dev), GFP_KERNEL);
if (!gpio_kuka) {
return -ENOMEM;
}
gpio = of_get_named_gpio_flags(kuka_gpio_node, "gpio_kuka", 0, &flag);
if (!gpio_is_valid(gpio)) {
printk("kuka-gpio: %d is invalid\n", gpio); return -ENODEV;
}
if (gpio_request(gpio, "gpio_kuka")) {
printk("gpio %d request failed!\n", gpio);
gpio_free(gpio);
return -ENODEV;
}
gpio_kuka->gpio = gpio;
gpio_kuka->nd = pdev->dev.of_node;
gpio_kuka->gpio_enable_value = (flag == OF_GPIO_ACTIVE_LOW) ? 0:1;
gpio_direction_output(gpio_kuka->gpio, gpio_kuka->gpio_enable_value);
printk("kuka gpio putout\n");
alloc_chrdev_region(&gpio_kuka->dev_id, 0, 1, pdev->name);
gpio_kuka->major = MAJOR(gpio_kuka->dev_id);
cdev_init(&gpio_kuka->cdev, &gpio_kuka_fops);
cdev_add(&gpio_kuka->cdev, gpio_kuka->dev_id, 1);
gpio_kuka_class = class_create(THIS_MODULE, pdev->name);
gpio_kuka->device = device_create(gpio_kuka_class, NULL, gpio_kuka->dev_id, NULL, pdev->name);
gpio_kuka->device->gpio = gpio_kuka->gpio;
return 0;
}
static int gpio_kuka_remove(struct platform_device *pdev)
{
gpio_free(gpio_kuka->gpio);
cdev_del(&gpio_kuka->cdev);
unregister_chrdev_region(gpio_kuka->dev_id, 1);
devm_kfree(&pdev->dev, gpio_kuka);
return 0;
}
static struct platform_driver gpio_driver_kuka = {
.driver = {
.owner = THIS_MODULE,
.name = "gpio_kuka",
.of_match_table = of_match_ptr(of_gpio_kuka_ids),
},
.probe = gpio_kuka_probe,
.remove = gpio_kuka_remove,
};
module_platform_driver(gpio_driver_kuka);
MODULE_LICENSE("GPL");