From df3514ac4aedd90f4eebf9eecda4de501d045d4d Mon Sep 17 00:00:00 2001 From: zeroway Date: Mon, 25 Sep 2017 19:27:58 +0800 Subject: [PATCH] Platform show and store skeleton --- debug/platform_driver_test/skeleton_ss.c | 183 ++++++++++++++++++++ debug/platform_driver_test/skeleton_ss.dtsi | 9 + debug/platform_driver_test/skeleton_ss.h | 31 ++++ 3 files changed, 223 insertions(+) create mode 100644 debug/platform_driver_test/skeleton_ss.c create mode 100755 debug/platform_driver_test/skeleton_ss.dtsi create mode 100644 debug/platform_driver_test/skeleton_ss.h diff --git a/debug/platform_driver_test/skeleton_ss.c b/debug/platform_driver_test/skeleton_ss.c new file mode 100644 index 0000000..5357a39 --- /dev/null +++ b/debug/platform_driver_test/skeleton_ss.c @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "skeleton_ss.h" + +/* cat egpios_debug */ +static ssize_t egpios_debug_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + int size = 0; + struct skleton_chip *chip; + + chip = dev_get_drvdata(dev); + + size = sprintf(buf, "%s value is %d\n", chip->pd[chip->pin_name_index]->name, gpio_get_value(chip->pd[chip->pin_name_index]->gpio_pin)); + return size; +} + +/* echo > egpios_debug */ +static ssize_t egpios_debug_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct skleton_chip *chip; + + chip = dev_get_drvdata(dev); + + sscanf(buf, "%d %d", &chip->pin_name_index, &chip->value); + gpio_set_value(chip->pd[chip->pin_name_index]->gpio_pin, chip->value); + return count; +} + +static DEVICE_ATTR(egpios_debug, S_IRUGO | S_IWUSR, egpios_debug_show, egpios_debug_store); + +static struct attribute *egpios_attrs[] = { + &dev_attr_egpios_debug.attr, + NULL, +}; + +static const struct attribute_group egpios_attr_group = { + .attrs = egpios_attrs, +}; + +static int skeleton_ss_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + int i; + enum of_gpio_flags flag; + struct skleton_chip *chip; + + int gpio_nr; + int ret; + + gpio_nr = sizeof(dts_name) / sizeof(dts_name[0]); + + /* alloc for chip point */ + chip = devm_kzalloc(&pdev->dev, sizeof(struct skleton_chip), GFP_KERNEL); + if (!chip) + { + printk("no memory\n"); + ret = -ENOMEM; + } + + /* alloc memory for array head */ + chip->pd = devm_kzalloc(&pdev->dev, sizeof(struct pin_desc *) * gpio_nr, GFP_KERNEL); + if (!chip->pd) + { + printk("no memory\n"); + ret = -ENOMEM; + } + + /* alloc memory for every point in the array */ + for (i = 0; i < gpio_nr; i++) + { + chip->pd[i] = devm_kzalloc(&pdev->dev, sizeof(struct pin_desc), GFP_KERNEL); + if (!chip->pd[i]) + { + printk("no memory\n"); + ret = -ENOMEM; + } + } + + /* set pdata */ + dev_set_drvdata(&pdev->dev, (void *)chip); + + /* make the pin desc names */ + for (i = 0; i < gpio_nr; i++) + strcpy(chip->pd[i]->name, dts_name[i]); + + /* make all pins active */ + for (i = 0; i < gpio_nr; i++) + { + chip->pd[i]->gpio_pin = of_get_named_gpio_flags(node, chip->pd[i]->name, 0, &flag); + + /* ROCKCHIP gpio active high and low is reverse */ + chip->pd[i]->gpio_active_flag = !flag; + + ret = devm_gpio_request(&pdev->dev, chip->pd[i]->gpio_pin, chip->pd[i]->name); + if (ret) + { + printk("%s error\n", chip->pd[i]->name); + } + else + { + ret = gpio_direction_output(chip->pd[i]->gpio_pin, chip->pd[i]->gpio_active_flag); +#ifdef READ_VALUE_BACK + printk("%s[%d]\n", chip->pd[i]->name, gpio_get_value(chip->pd[i]->gpio_pin)); +#endif + } + } + + /* sysfs */ + ret = sysfs_create_group(&pdev->dev.kobj, &egpios_attr_group); + if (ret) + { + printk("failed to create sysfs device attributes\n"); + return -1; + } + return 0; +} + +static int skeleton_ss_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &egpios_attr_group); + printk("%s, %d\n", __FUNCTION__, __LINE__); + + return 0; +} + +static const struct of_device_id skeleton_ss_dt_ids[] = { + {.compatible = "skeleton, compatible",}, + {}, +}; + +int skeleton_ss_suspend(struct platform_device *pdev, pm_message_t state) +{ + printk("%s, %d\n", __FUNCTION__, __LINE__); + return 0; +} + +int skeleton_ss_resume(struct platform_device *pdev) +{ + int i; + int gpio_nr; + struct skleton_chip *chip; + + gpio_nr = sizeof(dts_name) / sizeof(dts_name[0]); + chip = dev_get_drvdata(&pdev->dev); + + printk("%s, %d\n", __FUNCTION__, __LINE__); + + /* active all */ + for (i = 0; i < gpio_nr; i++) + gpio_set_value(chip->pd[i]->gpio_pin, chip->pd[i]->gpio_active_flag); + + return 0; +} + +static struct platform_driver skeleton_ss = { + .driver = { + .name = "skeleton example", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(skeleton_ss_dt_ids), + }, + .probe = skeleton_ss_probe, + .remove = skeleton_ss_remove, + .suspend = skeleton_ss_suspend, + .resume = skeleton_ss_resume, +}; + +module_platform_driver(skeleton_ss); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("zeroway "); +MODULE_DESCRIPTION("skeleton"); diff --git a/debug/platform_driver_test/skeleton_ss.dtsi b/debug/platform_driver_test/skeleton_ss.dtsi new file mode 100755 index 0000000..a4b3e6b --- /dev/null +++ b/debug/platform_driver_test/skeleton_ss.dtsi @@ -0,0 +1,9 @@ +/ { + skeleton_gpios { + compatible = "skeleton, compatible"; + + pin_a_name = <&gpio5 GPIO_C0 GPIO_ACTIVE_HIGH>; + pin_b_name = <&gpio8 GPIO_B0 GPIO_ACTIVE_HIGH>; + pin_c_name = <&gpio8 GPIO_B1 GPIO_ACTIVE_LOW>; + }; +}; diff --git a/debug/platform_driver_test/skeleton_ss.h b/debug/platform_driver_test/skeleton_ss.h new file mode 100644 index 0000000..38a6fa9 --- /dev/null +++ b/debug/platform_driver_test/skeleton_ss.h @@ -0,0 +1,31 @@ +#ifndef _SKELETON_H_ +#define _SKELETON_H_ + +/* + * Describe a pin + * gpio_pin : gpio pin number + * name : gpio name + */ +struct pin_desc { + int gpio_pin; + int gpio_active_flag; + char name[20]; +}; + +/* skeleton gpios, pdata or chip */ +struct skleton_chip { + int pin_name_index; + int value; + + /* a struct point array which contain of gpio_nr struct point */ + struct pin_desc **pd; +}; + +/* equal to dts pin name which is low case in pcb file */ +const char *dts_name[] = { + "pin_a_name", + "pin_b_name", + "pin_c_nmae", +}; + +#endif