基于MTK平台的Android Linux驱动
1、DTS配置如下
gpio_sample: gpio_sample {
compatible = "mediatek,gpio-sample";
input,high-gpio = <&pio 77 GPIO_ACTIVE_HIGH>;
input,low-gpio = <&pio 70 GPIO_ACTIVE_HIGH>;
output-gpio = <&pio 78 GPIO_ACTIVE_HIGH>;
irq-gpio = <&pio 10 GPIO_ACTIVE_HIGH>;
status = "okay";
};
2、驱动文件如下
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/fcntl.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/uaccess.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
// #define USE_DEVM_GPIO_API
#define USE_OF_GPIO_API
struct gpio_sample {
#ifdef USE_DEVM_GPIO_API
struct gpio_desc *input_low;
struct gpio_desc *input_high;
struct gpio_desc *output;
#endif
#ifdef USE_OF_GPIO_API
int input_low;
int input_high;
int output;
#endif
};
static int gpio_sample_dts_parse(struct device *dev,
struct gpio_sample *gsample)
{
int ret = 0;
#ifdef USE_DEVM_GPIO_API
/* 1.input */
gsample->input_high = devm_gpiod_get(dev, "input,high", GPIOD_IN);
if (IS_ERR(gsample->input_low))
return PTR_ERR(gsample->input_high);
gsample->input_low = devm_gpiod_get(dev, "input,low", GPIOD_IN);
if (IS_ERR(gsample->input_low))
return PTR_ERR(gsample->input_low);
/* 2.output */
gsample->output = devm_gpiod_get(dev, "output", GPIOD_OUT_LOW);
if (IS_ERR(gsample->output))
return PTR_ERR(gsample->output);
#endif /* USE_DEVM_GPIO_API */
#ifdef USE_OF_GPIO_API
// input low
gsample->input_low = of_get_named_gpio(dev->of_node,
"input,low-gpio", 0);
if (!gpio_is_valid(gsample->input_low)) {
pr_err("596 Missing dt property: input,low-gpio\n");
return -EINVAL;
}
ret = devm_gpio_request_one(dev, gsample->input_low, GPIOF_IN,
"input_low_gpio");
if (ret) {
pr_err("596 failed to get input_low gpio\n");
return ret;
}
// input high
gsample->input_high = of_get_named_gpio(dev->of_node,
"input,high-gpio", 0);
if (!gpio_is_valid(gsample->input_low)) {
pr_err("596 Missing dt property: input,high-gpio\n");
return -EINVAL;
}
ret = devm_gpio_request_one(dev, gsample->input_high, GPIOF_IN,
"input_high_gpio");
if (ret) {
pr_err("596 failed to get input_high gpio\n");
return ret;
}
pr_info("596 gsample->input_low = %d, gsample->input_high = %d\n",
gsample->input_low, gsample->input_high);
// output gpio
gsample->output = of_get_named_gpio(dev->of_node, "output-gpio", 0);
if (!gpio_is_valid(gsample->output)) {
pr_err("596 Missing dt property: output-gpio\n");
return -EINVAL;
}
ret = devm_gpio_request_one(dev, gsample->output, GPIOF_OUT_INIT_LOW,
"output_gpio");
if (ret) {
pr_err("596 failed to get output gpio\n");
return ret;
}
#endif /* USE_OF_GPIO_API */
return 0;
}
static int gpio_sample_operation(struct gpio_sample *gsample)
{
int in_low_val = 0, in_high_val = 0;
#ifdef USE_DEVM_GPIO_API
in_low_val = gpiod_get_value(gsample->input_low);
in_high_val = gpiod_get_value(gsample->input_high);
// set gpio output high
gpiod_set_value(gsample->output, 1);
#endif /* USE_DEVM_GPIO_API */
#ifdef USE_OF_GPIO_API
if (gpio_is_valid(gsample->input_low)) {
in_low_val = gpio_get_value(gsample->input_low);
}
if (gpio_is_valid(gsample->input_high)) {
in_high_val = gpio_get_value(gsample->input_high);
}
gpio_set_value(gsample->output, 1);
#endif
pr_info("596 gpio_sample_get_value in_low_val = %d,"
"in_high_val = %d\n", in_low_val, in_high_val);
return 0;
}
static int gpio_sample_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct gpio_sample *gsample;
int ret = 0;
gsample = devm_kzalloc(dev, sizeof(*gsample), GFP_KERNEL);
if (!gsample)
return -ENOMEM;
/* 1. Parse dts and init */
ret = gpio_sample_dts_parse(dev, gsample);
if (ret) {
pr_err("dts parse err!");
return ret;
}
/* 2. Get gpio value */
gpio_sample_operation(gsample);
return 0;
}
static int gpio_sample_remove(struct platform_device *dev)
{
pr_info("596 gpio_sample_remove enter.\n");
return 0;
}
const struct of_device_id gpio_sample_table[] = {
{ .compatible = "mediatek,gpio-sample" },
{}
};
static struct platform_driver gpio_sample_driver = {
.probe = gpio_sample_probe,
.remove = gpio_sample_remove,
.driver = {
.name = "gpio_sample",
.of_match_table = gpio_sample_table,
},
};
module_platform_driver(gpio_sample_driver);
MODULE_LICENSE("GPL");
标签:sample,01,input,示例,high,low,GPIO,gpio,gsample
From: https://www.cnblogs.com/hkcs596/p/17582212.html