gpio-bd71828.c 4.0 KB

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