Merge tag 'for-5.11/dm-fix' of git://git.kernel.org/pub/scm/linux/kernel/git/device...
[linux-2.6-microblaze.git] / drivers / gpio / gpio-bd70528.c
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018 ROHM Semiconductors
3 // gpio-bd70528.c ROHM BD70528MWV gpio driver
4
5 #include <linux/gpio/driver.h>
6 #include <linux/mfd/rohm-bd70528.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/regmap.h>
10
11 #define GPIO_IN_REG(offset) (BD70528_REG_GPIO1_IN + (offset) * 2)
12 #define GPIO_OUT_REG(offset) (BD70528_REG_GPIO1_OUT + (offset) * 2)
13
14 struct bd70528_gpio {
15         struct rohm_regmap_dev chip;
16         struct gpio_chip gpio;
17 };
18
19 static int bd70528_set_debounce(struct bd70528_gpio *bdgpio,
20                                 unsigned int offset, unsigned int debounce)
21 {
22         u8 val;
23
24         switch (debounce) {
25         case 0:
26                 val = BD70528_DEBOUNCE_DISABLE;
27                 break;
28         case 1 ... 15000:
29                 val = BD70528_DEBOUNCE_15MS;
30                 break;
31         case 15001 ... 30000:
32                 val = BD70528_DEBOUNCE_30MS;
33                 break;
34         case 30001 ... 50000:
35                 val = BD70528_DEBOUNCE_50MS;
36                 break;
37         default:
38                 dev_err(bdgpio->chip.dev,
39                         "Invalid debounce value %u\n", debounce);
40                 return -EINVAL;
41         }
42         return regmap_update_bits(bdgpio->chip.regmap, GPIO_IN_REG(offset),
43                                  BD70528_DEBOUNCE_MASK, val);
44 }
45
46 static int bd70528_get_direction(struct gpio_chip *chip, unsigned int offset)
47 {
48         struct bd70528_gpio *bdgpio = gpiochip_get_data(chip);
49         int val, ret;
50
51         /* Do we need to do something to IRQs here? */
52         ret = regmap_read(bdgpio->chip.regmap, GPIO_OUT_REG(offset), &val);
53         if (ret) {
54                 dev_err(bdgpio->chip.dev, "Could not read gpio direction\n");
55                 return ret;
56         }
57         if (val & BD70528_GPIO_OUT_EN_MASK)
58                 return GPIO_LINE_DIRECTION_OUT;
59
60         return GPIO_LINE_DIRECTION_IN;
61 }
62
63 static int bd70528_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
64                                    unsigned long config)
65 {
66         struct bd70528_gpio *bdgpio = gpiochip_get_data(chip);
67
68         switch (pinconf_to_config_param(config)) {
69         case PIN_CONFIG_DRIVE_OPEN_DRAIN:
70                 return regmap_update_bits(bdgpio->chip.regmap,
71                                           GPIO_OUT_REG(offset),
72                                           BD70528_GPIO_DRIVE_MASK,
73                                           BD70528_GPIO_OPEN_DRAIN);
74                 break;
75         case PIN_CONFIG_DRIVE_PUSH_PULL:
76                 return regmap_update_bits(bdgpio->chip.regmap,
77                                           GPIO_OUT_REG(offset),
78                                           BD70528_GPIO_DRIVE_MASK,
79                                           BD70528_GPIO_PUSH_PULL);
80                 break;
81         case PIN_CONFIG_INPUT_DEBOUNCE:
82                 return bd70528_set_debounce(bdgpio, offset,
83                                             pinconf_to_config_argument(config));
84                 break;
85         default:
86                 break;
87         }
88         return -ENOTSUPP;
89 }
90
91 static int bd70528_direction_input(struct gpio_chip *chip, unsigned int offset)
92 {
93         struct bd70528_gpio *bdgpio = gpiochip_get_data(chip);
94
95         /* Do we need to do something to IRQs here? */
96         return regmap_update_bits(bdgpio->chip.regmap, GPIO_OUT_REG(offset),
97                                  BD70528_GPIO_OUT_EN_MASK,
98                                  BD70528_GPIO_OUT_DISABLE);
99 }
100
101 static void bd70528_gpio_set(struct gpio_chip *chip, unsigned int offset,
102                              int value)
103 {
104         int ret;
105         struct bd70528_gpio *bdgpio = gpiochip_get_data(chip);
106         u8 val = (value) ? BD70528_GPIO_OUT_HI : BD70528_GPIO_OUT_LO;
107
108         ret = regmap_update_bits(bdgpio->chip.regmap, GPIO_OUT_REG(offset),
109                                  BD70528_GPIO_OUT_MASK, val);
110         if (ret)
111                 dev_err(bdgpio->chip.dev, "Could not set gpio to %d\n", value);
112 }
113
114 static int bd70528_direction_output(struct gpio_chip *chip, unsigned int offset,
115                                     int value)
116 {
117         struct bd70528_gpio *bdgpio = gpiochip_get_data(chip);
118
119         bd70528_gpio_set(chip, offset, value);
120         return regmap_update_bits(bdgpio->chip.regmap, GPIO_OUT_REG(offset),
121                                  BD70528_GPIO_OUT_EN_MASK,
122                                  BD70528_GPIO_OUT_ENABLE);
123 }
124
125 #define GPIO_IN_STATE_MASK(offset) (BD70528_GPIO_IN_STATE_BASE << (offset))
126
127 static int bd70528_gpio_get_o(struct bd70528_gpio *bdgpio, unsigned int offset)
128 {
129         int ret;
130         unsigned int val;
131
132         ret = regmap_read(bdgpio->chip.regmap, GPIO_OUT_REG(offset), &val);
133         if (!ret)
134                 ret = !!(val & BD70528_GPIO_OUT_MASK);
135         else
136                 dev_err(bdgpio->chip.dev, "GPIO (out) state read failed\n");
137
138         return ret;
139 }
140
141 static int bd70528_gpio_get_i(struct bd70528_gpio *bdgpio, unsigned int offset)
142 {
143         unsigned int val;
144         int ret;
145
146         ret = regmap_read(bdgpio->chip.regmap, BD70528_REG_GPIO_STATE, &val);
147
148         if (!ret)
149                 ret = !(val & GPIO_IN_STATE_MASK(offset));
150         else
151                 dev_err(bdgpio->chip.dev, "GPIO (in) state read failed\n");
152
153         return ret;
154 }
155
156 static int bd70528_gpio_get(struct gpio_chip *chip, unsigned int offset)
157 {
158         int ret;
159         struct bd70528_gpio *bdgpio = gpiochip_get_data(chip);
160
161         /*
162          * There is a race condition where someone might be changing the
163          * GPIO direction after we get it but before we read the value. But
164          * application design where GPIO direction may be changed just when
165          * we read GPIO value would be pointless as reader could not know
166          * whether the returned high/low state is caused by input or output.
167          * Or then there must be other ways to mitigate the issue. Thus
168          * locking would make no sense.
169          */
170         ret = bd70528_get_direction(chip, offset);
171         if (ret == GPIO_LINE_DIRECTION_OUT)
172                 ret = bd70528_gpio_get_o(bdgpio, offset);
173         else if (ret == GPIO_LINE_DIRECTION_IN)
174                 ret = bd70528_gpio_get_i(bdgpio, offset);
175         else
176                 dev_err(bdgpio->chip.dev, "failed to read GPIO direction\n");
177
178         return ret;
179 }
180
181 static int bd70528_probe(struct platform_device *pdev)
182 {
183         struct bd70528_gpio *bdgpio;
184         struct rohm_regmap_dev *bd70528;
185         int ret;
186
187         bd70528 = dev_get_drvdata(pdev->dev.parent);
188         if (!bd70528) {
189                 dev_err(&pdev->dev, "No MFD driver data\n");
190                 return -EINVAL;
191         }
192
193         bdgpio = devm_kzalloc(&pdev->dev, sizeof(*bdgpio),
194                               GFP_KERNEL);
195         if (!bdgpio)
196                 return -ENOMEM;
197         bdgpio->chip.dev = &pdev->dev;
198         bdgpio->gpio.parent = pdev->dev.parent;
199         bdgpio->gpio.label = "bd70528-gpio";
200         bdgpio->gpio.owner = THIS_MODULE;
201         bdgpio->gpio.get_direction = bd70528_get_direction;
202         bdgpio->gpio.direction_input = bd70528_direction_input;
203         bdgpio->gpio.direction_output = bd70528_direction_output;
204         bdgpio->gpio.set_config = bd70528_gpio_set_config;
205         bdgpio->gpio.can_sleep = true;
206         bdgpio->gpio.get = bd70528_gpio_get;
207         bdgpio->gpio.set = bd70528_gpio_set;
208         bdgpio->gpio.ngpio = 4;
209         bdgpio->gpio.base = -1;
210 #ifdef CONFIG_OF_GPIO
211         bdgpio->gpio.of_node = pdev->dev.parent->of_node;
212 #endif
213         bdgpio->chip.regmap = bd70528->regmap;
214
215         ret = devm_gpiochip_add_data(&pdev->dev, &bdgpio->gpio,
216                                      bdgpio);
217         if (ret)
218                 dev_err(&pdev->dev, "gpio_init: Failed to add bd70528-gpio\n");
219
220         return ret;
221 }
222
223 static struct platform_driver bd70528_gpio = {
224         .driver = {
225                 .name = "bd70528-gpio"
226         },
227         .probe = bd70528_probe,
228 };
229
230 module_platform_driver(bd70528_gpio);
231
232 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
233 MODULE_DESCRIPTION("BD70528 voltage regulator driver");
234 MODULE_LICENSE("GPL");
235 MODULE_ALIAS("platform:bd70528-gpio");