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