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