^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (C) 2018 ROHM Semiconductors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/mfd/rohm-bd71828.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define GPIO_OUT_REG(off) (BD71828_REG_GPIO_CTRL1 + (off))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define HALL_GPIO_OFFSET 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct bd71828_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct rohm_regmap_dev chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) struct gpio_chip gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static void bd71828_gpio_set(struct gpio_chip *chip, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) u8 val = (value) ? BD71828_GPIO_OUT_HI : BD71828_GPIO_OUT_LO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * The HALL input pin can only be used as input. If this is the pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * we are dealing with - then we are done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (offset == HALL_GPIO_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ret = regmap_update_bits(bdgpio->chip.regmap, GPIO_OUT_REG(offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) BD71828_GPIO_OUT_MASK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) dev_err(bdgpio->chip.dev, "Could not set gpio to %d\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int bd71828_gpio_get(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (offset == HALL_GPIO_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ret = regmap_read(bdgpio->chip.regmap, BD71828_REG_IO_STAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ret = regmap_read(bdgpio->chip.regmap, GPIO_OUT_REG(offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ret = (val & BD71828_GPIO_OUT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int bd71828_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned long config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (offset == HALL_GPIO_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) switch (pinconf_to_config_param(config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case PIN_CONFIG_DRIVE_OPEN_DRAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return regmap_update_bits(bdgpio->chip.regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) GPIO_OUT_REG(offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) BD71828_GPIO_DRIVE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) BD71828_GPIO_OPEN_DRAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case PIN_CONFIG_DRIVE_PUSH_PULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return regmap_update_bits(bdgpio->chip.regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) GPIO_OUT_REG(offset),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) BD71828_GPIO_DRIVE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) BD71828_GPIO_PUSH_PULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int bd71828_get_direction(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * Pin usage is selected by OTP data. We can't read it runtime. Hence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * we trust that if the pin is not excluded by "gpio-reserved-ranges"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * the OTP configuration is set to OUT. (Other pins but HALL input pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * on BD71828 can't really be used for general purpose input - input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * states are used for specific cases like regulator control or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * PMIC_ON_REQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (offset == HALL_GPIO_OFFSET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return GPIO_LINE_DIRECTION_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return GPIO_LINE_DIRECTION_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static int bd71828_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct bd71828_gpio *bdgpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct rohm_regmap_dev *bd71828;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) bd71828 = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (!bd71828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) dev_err(&pdev->dev, "No MFD driver data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) bdgpio = devm_kzalloc(&pdev->dev, sizeof(*bdgpio),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (!bdgpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bdgpio->chip.dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bdgpio->gpio.parent = pdev->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) bdgpio->gpio.label = "bd71828-gpio";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) bdgpio->gpio.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) bdgpio->gpio.get_direction = bd71828_get_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) bdgpio->gpio.set_config = bd71828_gpio_set_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) bdgpio->gpio.can_sleep = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) bdgpio->gpio.get = bd71828_gpio_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) bdgpio->gpio.set = bd71828_gpio_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) bdgpio->gpio.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * See if we need some implementation to mark some PINs as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * not controllable based on DT info or if core can handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * "gpio-reserved-ranges" and exclude them from control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) bdgpio->gpio.ngpio = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) bdgpio->gpio.of_node = pdev->dev.parent->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) bdgpio->chip.regmap = bd71828->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return devm_gpiochip_add_data(&pdev->dev, &bdgpio->gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) bdgpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static struct platform_driver bd71828_gpio = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .name = "bd71828-gpio"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .probe = bd71828_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) module_platform_driver(bd71828_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) MODULE_DESCRIPTION("BD71828 voltage regulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) MODULE_ALIAS("platform:bd71828-gpio");