Lines Matching +full:gpio +full:-
1 // SPDX-License-Identifier: GPL-2.0-only
3 * regmap based generic GPIO driver
8 #include <linux/gpio/driver.h>
9 #include <linux/gpio/regmap.h>
27 int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
42 static int gpio_regmap_simple_xlate(struct gpio_regmap *gpio, in gpio_regmap_simple_xlate() argument
46 unsigned int line = offset % gpio->ngpio_per_reg; in gpio_regmap_simple_xlate()
47 unsigned int stride = offset / gpio->ngpio_per_reg; in gpio_regmap_simple_xlate()
49 *reg = base + stride * gpio->reg_stride; in gpio_regmap_simple_xlate()
57 struct gpio_regmap *gpio = gpiochip_get_data(chip); in gpio_regmap_get() local
62 if (gpio->reg_dat_base) in gpio_regmap_get()
63 base = gpio_regmap_addr(gpio->reg_dat_base); in gpio_regmap_get()
65 base = gpio_regmap_addr(gpio->reg_set_base); in gpio_regmap_get()
67 ret = gpio->reg_mask_xlate(gpio, base, offset, ®, &mask); in gpio_regmap_get()
71 ret = regmap_read(gpio->regmap, reg, &val); in gpio_regmap_get()
81 struct gpio_regmap *gpio = gpiochip_get_data(chip); in gpio_regmap_set() local
82 unsigned int base = gpio_regmap_addr(gpio->reg_set_base); in gpio_regmap_set()
85 gpio->reg_mask_xlate(gpio, base, offset, ®, &mask); in gpio_regmap_set()
87 regmap_update_bits(gpio->regmap, reg, mask, mask); in gpio_regmap_set()
89 regmap_update_bits(gpio->regmap, reg, mask, 0); in gpio_regmap_set()
95 struct gpio_regmap *gpio = gpiochip_get_data(chip); in gpio_regmap_set_with_clear() local
99 base = gpio_regmap_addr(gpio->reg_set_base); in gpio_regmap_set_with_clear()
101 base = gpio_regmap_addr(gpio->reg_clr_base); in gpio_regmap_set_with_clear()
103 gpio->reg_mask_xlate(gpio, base, offset, ®, &mask); in gpio_regmap_set_with_clear()
104 regmap_write(gpio->regmap, reg, mask); in gpio_regmap_set_with_clear()
110 struct gpio_regmap *gpio = gpiochip_get_data(chip); in gpio_regmap_get_direction() local
114 if (gpio->reg_dir_out_base) { in gpio_regmap_get_direction()
115 base = gpio_regmap_addr(gpio->reg_dir_out_base); in gpio_regmap_get_direction()
117 } else if (gpio->reg_dir_in_base) { in gpio_regmap_get_direction()
118 base = gpio_regmap_addr(gpio->reg_dir_in_base); in gpio_regmap_get_direction()
121 return -EOPNOTSUPP; in gpio_regmap_get_direction()
124 ret = gpio->reg_mask_xlate(gpio, base, offset, ®, &mask); in gpio_regmap_get_direction()
128 ret = regmap_read(gpio->regmap, reg, &val); in gpio_regmap_get_direction()
141 struct gpio_regmap *gpio = gpiochip_get_data(chip); in gpio_regmap_set_direction() local
145 if (gpio->reg_dir_out_base) { in gpio_regmap_set_direction()
146 base = gpio_regmap_addr(gpio->reg_dir_out_base); in gpio_regmap_set_direction()
148 } else if (gpio->reg_dir_in_base) { in gpio_regmap_set_direction()
149 base = gpio_regmap_addr(gpio->reg_dir_in_base); in gpio_regmap_set_direction()
152 return -EOPNOTSUPP; in gpio_regmap_set_direction()
155 ret = gpio->reg_mask_xlate(gpio, base, offset, ®, &mask); in gpio_regmap_set_direction()
164 return regmap_update_bits(gpio->regmap, reg, mask, val); in gpio_regmap_set_direction()
181 void gpio_regmap_set_drvdata(struct gpio_regmap *gpio, void *data) in gpio_regmap_set_drvdata() argument
183 gpio->driver_data = data; in gpio_regmap_set_drvdata()
187 void *gpio_regmap_get_drvdata(struct gpio_regmap *gpio) in gpio_regmap_get_drvdata() argument
189 return gpio->driver_data; in gpio_regmap_get_drvdata()
194 * gpio_regmap_register() - Register a generic regmap GPIO controller
201 struct gpio_regmap *gpio; in gpio_regmap_register() local
205 if (!config->parent) in gpio_regmap_register()
206 return ERR_PTR(-EINVAL); in gpio_regmap_register()
208 if (!config->ngpio) in gpio_regmap_register()
209 return ERR_PTR(-EINVAL); in gpio_regmap_register()
212 if (!config->reg_dat_base && !config->reg_set_base) in gpio_regmap_register()
213 return ERR_PTR(-EINVAL); in gpio_regmap_register()
216 if ((config->reg_dir_out_base || config->reg_dir_in_base) && in gpio_regmap_register()
217 (!config->reg_dat_base || !config->reg_set_base)) in gpio_regmap_register()
218 return ERR_PTR(-EINVAL); in gpio_regmap_register()
221 if (config->reg_dir_out_base && config->reg_dir_in_base) in gpio_regmap_register()
222 return ERR_PTR(-EINVAL); in gpio_regmap_register()
224 gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); in gpio_regmap_register()
225 if (!gpio) in gpio_regmap_register()
226 return ERR_PTR(-ENOMEM); in gpio_regmap_register()
228 gpio->parent = config->parent; in gpio_regmap_register()
229 gpio->regmap = config->regmap; in gpio_regmap_register()
230 gpio->ngpio_per_reg = config->ngpio_per_reg; in gpio_regmap_register()
231 gpio->reg_stride = config->reg_stride; in gpio_regmap_register()
232 gpio->reg_mask_xlate = config->reg_mask_xlate; in gpio_regmap_register()
233 gpio->reg_dat_base = config->reg_dat_base; in gpio_regmap_register()
234 gpio->reg_set_base = config->reg_set_base; in gpio_regmap_register()
235 gpio->reg_clr_base = config->reg_clr_base; in gpio_regmap_register()
236 gpio->reg_dir_in_base = config->reg_dir_in_base; in gpio_regmap_register()
237 gpio->reg_dir_out_base = config->reg_dir_out_base; in gpio_regmap_register()
240 if (!gpio->ngpio_per_reg) in gpio_regmap_register()
241 gpio->ngpio_per_reg = config->ngpio; in gpio_regmap_register()
244 if (!gpio->reg_stride) in gpio_regmap_register()
245 gpio->reg_stride = 1; in gpio_regmap_register()
247 if (!gpio->reg_mask_xlate) in gpio_regmap_register()
248 gpio->reg_mask_xlate = gpio_regmap_simple_xlate; in gpio_regmap_register()
250 chip = &gpio->gpio_chip; in gpio_regmap_register()
251 chip->parent = config->parent; in gpio_regmap_register()
252 chip->base = -1; in gpio_regmap_register()
253 chip->ngpio = config->ngpio; in gpio_regmap_register()
254 chip->names = config->names; in gpio_regmap_register()
255 chip->label = config->label ?: dev_name(config->parent); in gpio_regmap_register()
261 * The only regmap type which uses fast_io is regmap-mmio. For now, in gpio_regmap_register()
264 chip->can_sleep = true; in gpio_regmap_register()
266 chip->get = gpio_regmap_get; in gpio_regmap_register()
267 if (gpio->reg_set_base && gpio->reg_clr_base) in gpio_regmap_register()
268 chip->set = gpio_regmap_set_with_clear; in gpio_regmap_register()
269 else if (gpio->reg_set_base) in gpio_regmap_register()
270 chip->set = gpio_regmap_set; in gpio_regmap_register()
272 if (gpio->reg_dir_in_base || gpio->reg_dir_out_base) { in gpio_regmap_register()
273 chip->get_direction = gpio_regmap_get_direction; in gpio_regmap_register()
274 chip->direction_input = gpio_regmap_direction_input; in gpio_regmap_register()
275 chip->direction_output = gpio_regmap_direction_output; in gpio_regmap_register()
278 ret = gpiochip_add_data(chip, gpio); in gpio_regmap_register()
282 if (config->irq_domain) { in gpio_regmap_register()
283 ret = gpiochip_irqchip_add_domain(chip, config->irq_domain); in gpio_regmap_register()
288 return gpio; in gpio_regmap_register()
293 kfree(gpio); in gpio_regmap_register()
299 * gpio_regmap_unregister() - Unregister a generic regmap GPIO controller
300 * @gpio: gpio_regmap device to unregister
302 void gpio_regmap_unregister(struct gpio_regmap *gpio) in gpio_regmap_unregister() argument
304 gpiochip_remove(&gpio->gpio_chip); in gpio_regmap_unregister()
305 kfree(gpio); in gpio_regmap_unregister()
315 * devm_gpio_regmap_register() - resource managed gpio_regmap_register()
316 * @dev: device that is registering this GPIO device
319 * Managed gpio_regmap_register(). For generic regmap GPIO device registered by
328 struct gpio_regmap **ptr, *gpio; in devm_gpio_regmap_register() local
333 return ERR_PTR(-ENOMEM); in devm_gpio_regmap_register()
335 gpio = gpio_regmap_register(config); in devm_gpio_regmap_register()
336 if (!IS_ERR(gpio)) { in devm_gpio_regmap_register()
337 *ptr = gpio; in devm_gpio_regmap_register()
343 return gpio; in devm_gpio_regmap_register()
348 MODULE_DESCRIPTION("GPIO generic regmap driver core");