Platform show and store skeleton

This commit is contained in:
zeroway
2017-09-25 19:27:58 +08:00
parent bffcb5d4f0
commit df3514ac4a
3 changed files with 223 additions and 0 deletions

View File

@ -0,0 +1,183 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#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 <pin_index> <val> > 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 <M_O_Bz@163.com>");
MODULE_DESCRIPTION("skeleton");

View File

@ -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>;
};
};

View File

@ -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