0001
0002
0003
0004 #include <linux/gpio/driver.h>
0005 #include <linux/mfd/rohm-bd71828.h>
0006 #include <linux/module.h>
0007 #include <linux/platform_device.h>
0008 #include <linux/regmap.h>
0009
0010 #define GPIO_OUT_REG(off) (BD71828_REG_GPIO_CTRL1 + (off))
0011 #define HALL_GPIO_OFFSET 3
0012
0013 struct bd71828_gpio {
0014 struct regmap *regmap;
0015 struct device *dev;
0016 struct gpio_chip gpio;
0017 };
0018
0019 static void bd71828_gpio_set(struct gpio_chip *chip, unsigned int offset,
0020 int value)
0021 {
0022 int ret;
0023 struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
0024 u8 val = (value) ? BD71828_GPIO_OUT_HI : BD71828_GPIO_OUT_LO;
0025
0026
0027
0028
0029
0030 if (offset == HALL_GPIO_OFFSET)
0031 return;
0032
0033 ret = regmap_update_bits(bdgpio->regmap, GPIO_OUT_REG(offset),
0034 BD71828_GPIO_OUT_MASK, val);
0035 if (ret)
0036 dev_err(bdgpio->dev, "Could not set gpio to %d\n", value);
0037 }
0038
0039 static int bd71828_gpio_get(struct gpio_chip *chip, unsigned int offset)
0040 {
0041 int ret;
0042 unsigned int val;
0043 struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
0044
0045 if (offset == HALL_GPIO_OFFSET)
0046 ret = regmap_read(bdgpio->regmap, BD71828_REG_IO_STAT,
0047 &val);
0048 else
0049 ret = regmap_read(bdgpio->regmap, GPIO_OUT_REG(offset),
0050 &val);
0051 if (!ret)
0052 ret = (val & BD71828_GPIO_OUT_MASK);
0053
0054 return ret;
0055 }
0056
0057 static int bd71828_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
0058 unsigned long config)
0059 {
0060 struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
0061
0062 if (offset == HALL_GPIO_OFFSET)
0063 return -ENOTSUPP;
0064
0065 switch (pinconf_to_config_param(config)) {
0066 case PIN_CONFIG_DRIVE_OPEN_DRAIN:
0067 return regmap_update_bits(bdgpio->regmap,
0068 GPIO_OUT_REG(offset),
0069 BD71828_GPIO_DRIVE_MASK,
0070 BD71828_GPIO_OPEN_DRAIN);
0071 case PIN_CONFIG_DRIVE_PUSH_PULL:
0072 return regmap_update_bits(bdgpio->regmap,
0073 GPIO_OUT_REG(offset),
0074 BD71828_GPIO_DRIVE_MASK,
0075 BD71828_GPIO_PUSH_PULL);
0076 default:
0077 break;
0078 }
0079 return -ENOTSUPP;
0080 }
0081
0082 static int bd71828_get_direction(struct gpio_chip *chip, unsigned int offset)
0083 {
0084
0085
0086
0087
0088
0089
0090
0091
0092 if (offset == HALL_GPIO_OFFSET)
0093 return GPIO_LINE_DIRECTION_IN;
0094
0095 return GPIO_LINE_DIRECTION_OUT;
0096 }
0097
0098 static int bd71828_probe(struct platform_device *pdev)
0099 {
0100 struct device *dev = &pdev->dev;
0101 struct bd71828_gpio *bdgpio;
0102
0103 bdgpio = devm_kzalloc(dev, sizeof(*bdgpio), GFP_KERNEL);
0104 if (!bdgpio)
0105 return -ENOMEM;
0106
0107 bdgpio->dev = dev;
0108 bdgpio->gpio.parent = dev->parent;
0109 bdgpio->gpio.label = "bd71828-gpio";
0110 bdgpio->gpio.owner = THIS_MODULE;
0111 bdgpio->gpio.get_direction = bd71828_get_direction;
0112 bdgpio->gpio.set_config = bd71828_gpio_set_config;
0113 bdgpio->gpio.can_sleep = true;
0114 bdgpio->gpio.get = bd71828_gpio_get;
0115 bdgpio->gpio.set = bd71828_gpio_set;
0116 bdgpio->gpio.base = -1;
0117
0118
0119
0120
0121
0122
0123 bdgpio->gpio.ngpio = 4;
0124 bdgpio->regmap = dev_get_regmap(dev->parent, NULL);
0125 if (!bdgpio->regmap)
0126 return -ENODEV;
0127
0128 return devm_gpiochip_add_data(dev, &bdgpio->gpio, bdgpio);
0129 }
0130
0131 static struct platform_driver bd71828_gpio = {
0132 .driver = {
0133 .name = "bd71828-gpio"
0134 },
0135 .probe = bd71828_probe,
0136 };
0137
0138 module_platform_driver(bd71828_gpio);
0139
0140 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
0141 MODULE_DESCRIPTION("BD71828 voltage regulator driver");
0142 MODULE_LICENSE("GPL");
0143 MODULE_ALIAS("platform:bd71828-gpio");