01-[Linux][GPIO]GPIO编程示例代码

基于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");
posted @ 2023-07-26 13:24  596  阅读(237)  评论(0)    收藏  举报