说明:这里主要是基于Amlogic_S905X平台上实现的,其实gpio的控制都是通用的,使用的都是标准的gpio操作函数,跟平台无关。通过往节点写入1或者0来拉高拉低gpio来控制led灯的亮灭。
stvs9:/ $ cd sys/devices/led_ctrl.15/
stvs9:/sys/devices/led_ctrl.15 $ ls -l
total 0
lrwxrwxrwx 1 root root 0 2018-09-11 00:00 driver -> ../../bus/platform/drivers/led_ctrl
-rw-rw-rw- 1 root root 4096 2018-09-11 00:01 gpio_wps
-rw-rw-rw- 1 root root 4096 2018-09-11 00:01 gpio_zigbee
-rw-rw-rw- 1 root root 4096 2018-09-11 00:00 gpio_zwave
-r--r--r-- 1 root root 4096 2018-09-11 00:00 modalias
drwxr-xr-x 2 root root 0 1970-01-13 09:47 power
lrwxrwxrwx 1 root root 0 2018-09-11 00:00 subsystem -> ../../bus/platform
-rw-r--r-- 1 root root 4096 1970-01-13 09:47 uevent
stvs9:/sys/devices/led_ctrl.15 $ echo 1 > gpio_zigbee //打开led
stvs9:/sys/devices/led_ctrl.15 $ echo 0 > gpio_zigbee //关闭led
stvs9:/sys/devices/led_ctrl.15 $ echo 1 > gpio_zwave
stvs9:/sys/devices/led_ctrl.15 $ echo 0 > gpio_zwave
stvs9:/sys/devices/led_ctrl.15 $ echo 1 > gpio_wps
stvs9:/sys/devices/led_ctrl.15 $ echo 0 > gpio_wps
stvs9:/sys/devices/led_ctrl.15 $ cat gpio_zigbee //查看led电平
主要代码如下:
1、dts的配置:
led_ctrl {
compatible = "amlogic, led_ctrl";
dev_name = "led_ctrl";
status = "okay";
gpio_zigbee = <&gpio GPIOH_8 GPIO_ACTIVE_HIGH>;
gpio_zwave = <&gpio GPIOH_7 GPIO_ACTIVE_HIGH>;
gpio_wps = <&gpio GPIOH_6 GPIO_ACTIVE_HIGH>;
};
2、 具体驱动代码如下:
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/err.h>
static int gpio_zigbee;
static int gpio_zwave;
static int gpio_wps;
static ssize_t led_ctrl_gpio_zigbee_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", gpio_get_value(gpio_zigbee));
}
static ssize_t led_ctrl_gpio_zwave_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", gpio_get_value(gpio_zwave));
}
static ssize_t led_ctrl_gpio_wps_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", gpio_get_value(gpio_wps));
}
static ssize_t led_ctrl_gpio_zigbee_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
u8 wp;
u8 ret;
ret = sscanf(buf, "%x", (int *)&wp);
if (wp == 0) {
gpio_set_value(gpio_zigbee, 0);
pr_err("-czd-: _%s_ :gpio_zigbee off\n", __func__);
} else if (wp == 1) {
gpio_set_value(gpio_zigbee, 1);
pr_err("-czd-: _%s_ :gpio_zigbee on\n", __func__);
} else
pr_err("I only support 0 or 1 to ctrl led on or off\n");
return size;
}
static ssize_t led_ctrl_gpio_zwave_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
u8 wp;
u8 ret;
ret = sscanf(buf, "%x", (int *)&wp);
if (wp == 0) {
gpio_set_value(gpio_zwave, 0);
pr_err("-czd-: _%s_ :gpio_zwave off\n", __func__);
} else if (wp == 1) {
gpio_set_value(gpio_zwave, 1);
pr_err("-czd-: _%s_ :gpio_zwave on\n", __func__);
} else
pr_err("I only support 0 or 1 to ctrl led on or off\n");
return size;
}
static ssize_t led_ctrl_gpio_wps_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
u8 wp;
u8 ret;
ret = sscanf(buf, "%x", (int *)&wp);
if (wp == 0) {
gpio_set_value(gpio_wps, 0);
pr_err("-czd-: _%s_ :gpio_wps off\n", __func__);
} else if (wp == 1) {
gpio_set_value(gpio_wps, 1);
pr_err("-czd-: _%s_ :gpio_wps on\n", __func__);
} else
pr_err("I only support 0 or 1 to ctrl led on or off\n");
return size;
}
static DEVICE_ATTR(gpio_zigbee, 0664, led_ctrl_gpio_zigbee_show, led_ctrl_gpio_zigbee_store);
static DEVICE_ATTR(gpio_zwave, 0664, led_ctrl_gpio_zwave_show, led_ctrl_gpio_zwave_store);
static DEVICE_ATTR(gpio_wps, 0664, led_ctrl_gpio_wps_show, led_ctrl_gpio_wps_store);
static int led_ctrl_probe(struct platform_device *pdev)
{
struct device_node *led_ctrl_node = pdev->dev.of_node;
enum of_gpio_flags flags;
pr_err("---[czd]--- Enter %s\n", __func__);
gpio_zigbee = of_get_named_gpio_flags(led_ctrl_node,
"gpio_zigbee", 0, &flags);
pr_err("---[czd]--- gpio_zigbee is %d --\n", gpio_zigbee);
if (!gpio_is_valid(gpio_zigbee)) {
pr_err("gpio_zigbee: %d is invalid\n", gpio_zigbee);
return -ENODEV;
}
if (gpio_request(gpio_zigbee, "gpio_zigbee")) {
pr_err("gpio_zigbee: %d request failed!\n", gpio_zigbee);
gpio_free(gpio_zigbee);
return -ENODEV;
}
gpio_zwave = of_get_named_gpio_flags(led_ctrl_node,
"gpio_zwave", 0, &flags);
pr_err("---[czd]--- gpio_zwave is %d --\n", gpio_zwave);
if (!gpio_is_valid(gpio_zwave)) {
pr_err("gpio_zwave: %d is invalid\n", gpio_zwave);
return -ENODEV;
}
if (gpio_request(gpio_zwave, "gpio_zwave")) {
pr_err("gpio_zwave: %d request failed!\n", gpio_zwave);
gpio_free(gpio_zwave);
return -ENODEV;
}
gpio_wps = of_get_named_gpio_flags(led_ctrl_node,
"gpio_wps", 0, &flags);
pr_err("---[czd]--- gpio_wps is %d --\n", gpio_wps);
if (!gpio_is_valid(gpio_wps)) {
pr_err("gpio_wps: %d is invalid\n", gpio_wps);
return -ENODEV;
}
if (gpio_request(gpio_wps, "gpio_wps")) {
pr_err("gpio_wps: %d request failed!\n", gpio_wps);
gpio_free(gpio_wps);
return -ENODEV;
}
gpio_direction_output(gpio_zigbee, 0);
gpio_direction_output(gpio_zwave, 0);
gpio_direction_output(gpio_wps, 0);
device_create_file(&pdev->dev, &dev_attr_gpio_zigbee);
device_create_file(&pdev->dev, &dev_attr_gpio_zwave);
device_create_file(&pdev->dev, &dev_attr_gpio_wps);
pr_err("-czd- led_ctrl_probe sucess..\n");
return 0;
}
static struct of_device_id led_ctrl_match_table[] = {
{ .compatible = "amlogic, led_ctrl",},
{},
};
static int led_ctrl_remove(struct platform_device *pdv)
{
pr_err("led_ctrl_remove...\n");
return 0;
}
static struct platform_driver led_ctrl_driver = {
.driver = {
.name = "led_ctrl",
.owner = THIS_MODULE,
.of_match_table = led_ctrl_match_table,
},
.probe = led_ctrl_probe,
.remove = led_ctrl_remove,
};
static int led_ctrl_init(void)
{
pr_err("-czd-: led_ctrl_init start...\n");
platform_driver_register(&led_ctrl_driver);
return 0;
}
static void led_ctrl_exit(void)
{
pr_err("led_ctrl_exit ...\n");
platform_driver_unregister(&led_ctrl_driver);
}
module_init(led_ctrl_init);
module_exit(led_ctrl_exit);
MODULE_AUTHOR("caizd");
MODULE_DESCRIPTION("Device_create Driver");
MODULE_LICENSE("GPL");