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