xref: /linux/drivers/gpio/gpio-by-pinctrl.c (revision 1334d2a3b3235d062e5e1f51aebe7a64ed57cf72)
1*7671f494SAKASHI Takahiro // SPDX-License-Identifier: GPL-2.0
2*7671f494SAKASHI Takahiro //
3*7671f494SAKASHI Takahiro // Copyright (C) 2026 Linaro Inc.
4*7671f494SAKASHI Takahiro //   Author: AKASHI takahiro <takahiro.akashi@linaro.org>
5*7671f494SAKASHI Takahiro 
6*7671f494SAKASHI Takahiro #include <linux/errno.h>
7*7671f494SAKASHI Takahiro #include <linux/gpio/driver.h>
8*7671f494SAKASHI Takahiro #include <linux/mod_devicetable.h>
9*7671f494SAKASHI Takahiro #include <linux/module.h>
10*7671f494SAKASHI Takahiro #include <linux/pinctrl/consumer.h>
11*7671f494SAKASHI Takahiro #include <linux/platform_device.h>
12*7671f494SAKASHI Takahiro #include <linux/types.h>
13*7671f494SAKASHI Takahiro 
14*7671f494SAKASHI Takahiro #include "gpiolib.h"
15*7671f494SAKASHI Takahiro 
16*7671f494SAKASHI Takahiro static int pin_control_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
17*7671f494SAKASHI Takahiro {
18*7671f494SAKASHI Takahiro 	unsigned long config;
19*7671f494SAKASHI Takahiro 	int ret;
20*7671f494SAKASHI Takahiro 
21*7671f494SAKASHI Takahiro 	config = PIN_CONFIG_OUTPUT_ENABLE;
22*7671f494SAKASHI Takahiro 	ret = pinctrl_gpio_get_config(gc, offset, &config);
23*7671f494SAKASHI Takahiro 	if (ret)
24*7671f494SAKASHI Takahiro 		return ret;
25*7671f494SAKASHI Takahiro 	if (config)
26*7671f494SAKASHI Takahiro 		return GPIO_LINE_DIRECTION_OUT;
27*7671f494SAKASHI Takahiro 
28*7671f494SAKASHI Takahiro 	return GPIO_LINE_DIRECTION_IN;
29*7671f494SAKASHI Takahiro }
30*7671f494SAKASHI Takahiro 
31*7671f494SAKASHI Takahiro static int pin_control_gpio_direction_output(struct gpio_chip *chip,
32*7671f494SAKASHI Takahiro 					     unsigned int offset, int val)
33*7671f494SAKASHI Takahiro {
34*7671f494SAKASHI Takahiro 	return pinctrl_gpio_direction_output(chip, offset);
35*7671f494SAKASHI Takahiro }
36*7671f494SAKASHI Takahiro 
37*7671f494SAKASHI Takahiro static int pin_control_gpio_get(struct gpio_chip *chip, unsigned int offset)
38*7671f494SAKASHI Takahiro {
39*7671f494SAKASHI Takahiro 	unsigned long config;
40*7671f494SAKASHI Takahiro 	int ret;
41*7671f494SAKASHI Takahiro 
42*7671f494SAKASHI Takahiro 	config = PIN_CONFIG_LEVEL;
43*7671f494SAKASHI Takahiro 	ret = pinctrl_gpio_get_config(chip, offset, &config);
44*7671f494SAKASHI Takahiro 	if (ret)
45*7671f494SAKASHI Takahiro 		return ret;
46*7671f494SAKASHI Takahiro 
47*7671f494SAKASHI Takahiro 	return !!config;
48*7671f494SAKASHI Takahiro }
49*7671f494SAKASHI Takahiro 
50*7671f494SAKASHI Takahiro static int pin_control_gpio_set(struct gpio_chip *chip, unsigned int offset,
51*7671f494SAKASHI Takahiro 				int val)
52*7671f494SAKASHI Takahiro {
53*7671f494SAKASHI Takahiro 	unsigned long config;
54*7671f494SAKASHI Takahiro 
55*7671f494SAKASHI Takahiro 	config = pinconf_to_config_packed(PIN_CONFIG_LEVEL, val);
56*7671f494SAKASHI Takahiro 	return pinctrl_gpio_set_config(chip, offset, config);
57*7671f494SAKASHI Takahiro }
58*7671f494SAKASHI Takahiro 
59*7671f494SAKASHI Takahiro static int pin_control_gpio_probe(struct platform_device *pdev)
60*7671f494SAKASHI Takahiro {
61*7671f494SAKASHI Takahiro 	struct device *dev = &pdev->dev;
62*7671f494SAKASHI Takahiro 	struct gpio_chip *chip;
63*7671f494SAKASHI Takahiro 
64*7671f494SAKASHI Takahiro 	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
65*7671f494SAKASHI Takahiro 	if (!chip)
66*7671f494SAKASHI Takahiro 		return -ENOMEM;
67*7671f494SAKASHI Takahiro 
68*7671f494SAKASHI Takahiro 	chip->label = dev_name(dev);
69*7671f494SAKASHI Takahiro 	chip->parent = dev;
70*7671f494SAKASHI Takahiro 	chip->base = -1;
71*7671f494SAKASHI Takahiro 
72*7671f494SAKASHI Takahiro 	chip->request = gpiochip_generic_request;
73*7671f494SAKASHI Takahiro 	chip->free = gpiochip_generic_free;
74*7671f494SAKASHI Takahiro 	chip->get_direction = pin_control_gpio_get_direction;
75*7671f494SAKASHI Takahiro 	chip->direction_input = pinctrl_gpio_direction_input;
76*7671f494SAKASHI Takahiro 	chip->direction_output = pin_control_gpio_direction_output;
77*7671f494SAKASHI Takahiro 	chip->get = pin_control_gpio_get;
78*7671f494SAKASHI Takahiro 	chip->set = pin_control_gpio_set;
79*7671f494SAKASHI Takahiro 	chip->set_config = gpiochip_generic_config;
80*7671f494SAKASHI Takahiro 
81*7671f494SAKASHI Takahiro 	return devm_gpiochip_add_data(dev, chip, NULL);
82*7671f494SAKASHI Takahiro }
83*7671f494SAKASHI Takahiro 
84*7671f494SAKASHI Takahiro static const struct of_device_id pin_control_gpio_match[] = {
85*7671f494SAKASHI Takahiro 	{ .compatible = "scmi-pinctrl-gpio" },
86*7671f494SAKASHI Takahiro 	{ /* sentinel */ }
87*7671f494SAKASHI Takahiro };
88*7671f494SAKASHI Takahiro MODULE_DEVICE_TABLE(of, pin_control_gpio_match);
89*7671f494SAKASHI Takahiro 
90*7671f494SAKASHI Takahiro static struct platform_driver pin_control_gpio_driver = {
91*7671f494SAKASHI Takahiro 	.probe = pin_control_gpio_probe,
92*7671f494SAKASHI Takahiro 	.driver = {
93*7671f494SAKASHI Takahiro 		.name = "pin-control-gpio",
94*7671f494SAKASHI Takahiro 		.of_match_table = pin_control_gpio_match,
95*7671f494SAKASHI Takahiro 	},
96*7671f494SAKASHI Takahiro };
97*7671f494SAKASHI Takahiro module_platform_driver(pin_control_gpio_driver);
98*7671f494SAKASHI Takahiro 
99*7671f494SAKASHI Takahiro MODULE_AUTHOR("AKASHI Takahiro <takahiro.akashi@linaro.org>");
100*7671f494SAKASHI Takahiro MODULE_DESCRIPTION("Pinctrl based GPIO driver");
101*7671f494SAKASHI Takahiro MODULE_LICENSE("GPL");
102