Lines Matching +full:gpio +full:- +full:config

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, &reg, &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, &reg, &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, &reg, &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, &reg, &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, &reg, &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_get_drvdata(struct gpio_regmap *gpio) in gpio_regmap_get_drvdata() argument
183 return gpio->driver_data; in gpio_regmap_get_drvdata()
188 * gpio_regmap_register() - Register a generic regmap GPIO controller
189 * @config: configuration for gpio_regmap
193 struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config) in gpio_regmap_register() argument
195 struct gpio_regmap *gpio; in gpio_regmap_register() local
199 if (!config->parent) in gpio_regmap_register()
200 return ERR_PTR(-EINVAL); in gpio_regmap_register()
202 if (!config->ngpio) in gpio_regmap_register()
203 return ERR_PTR(-EINVAL); in gpio_regmap_register()
206 if (!config->reg_dat_base && !config->reg_set_base) in gpio_regmap_register()
207 return ERR_PTR(-EINVAL); in gpio_regmap_register()
210 if ((config->reg_dir_out_base || config->reg_dir_in_base) && in gpio_regmap_register()
211 (!config->reg_dat_base || !config->reg_set_base)) in gpio_regmap_register()
212 return ERR_PTR(-EINVAL); in gpio_regmap_register()
215 if (config->reg_dir_out_base && config->reg_dir_in_base) in gpio_regmap_register()
216 return ERR_PTR(-EINVAL); in gpio_regmap_register()
218 gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); in gpio_regmap_register()
219 if (!gpio) in gpio_regmap_register()
220 return ERR_PTR(-ENOMEM); in gpio_regmap_register()
222 gpio->parent = config->parent; in gpio_regmap_register()
223 gpio->driver_data = config->drvdata; in gpio_regmap_register()
224 gpio->regmap = config->regmap; in gpio_regmap_register()
225 gpio->ngpio_per_reg = config->ngpio_per_reg; in gpio_regmap_register()
226 gpio->reg_stride = config->reg_stride; in gpio_regmap_register()
227 gpio->reg_mask_xlate = config->reg_mask_xlate; in gpio_regmap_register()
228 gpio->reg_dat_base = config->reg_dat_base; in gpio_regmap_register()
229 gpio->reg_set_base = config->reg_set_base; in gpio_regmap_register()
230 gpio->reg_clr_base = config->reg_clr_base; in gpio_regmap_register()
231 gpio->reg_dir_in_base = config->reg_dir_in_base; in gpio_regmap_register()
232 gpio->reg_dir_out_base = config->reg_dir_out_base; in gpio_regmap_register()
235 if (!gpio->ngpio_per_reg) in gpio_regmap_register()
236 gpio->ngpio_per_reg = config->ngpio; in gpio_regmap_register()
239 if (!gpio->reg_stride) in gpio_regmap_register()
240 gpio->reg_stride = 1; in gpio_regmap_register()
242 if (!gpio->reg_mask_xlate) in gpio_regmap_register()
243 gpio->reg_mask_xlate = gpio_regmap_simple_xlate; in gpio_regmap_register()
245 chip = &gpio->gpio_chip; in gpio_regmap_register()
246 chip->parent = config->parent; in gpio_regmap_register()
247 chip->fwnode = config->fwnode; in gpio_regmap_register()
248 chip->base = -1; in gpio_regmap_register()
249 chip->ngpio = config->ngpio; in gpio_regmap_register()
250 chip->names = config->names; in gpio_regmap_register()
251 chip->label = config->label ?: dev_name(config->parent); in gpio_regmap_register()
257 * The only regmap type which uses fast_io is regmap-mmio. For now, in gpio_regmap_register()
260 chip->can_sleep = true; in gpio_regmap_register()
262 chip->get = gpio_regmap_get; in gpio_regmap_register()
263 if (gpio->reg_set_base && gpio->reg_clr_base) in gpio_regmap_register()
264 chip->set = gpio_regmap_set_with_clear; in gpio_regmap_register()
265 else if (gpio->reg_set_base) in gpio_regmap_register()
266 chip->set = gpio_regmap_set; in gpio_regmap_register()
268 if (gpio->reg_dir_in_base || gpio->reg_dir_out_base) { in gpio_regmap_register()
269 chip->get_direction = gpio_regmap_get_direction; in gpio_regmap_register()
270 chip->direction_input = gpio_regmap_direction_input; in gpio_regmap_register()
271 chip->direction_output = gpio_regmap_direction_output; in gpio_regmap_register()
274 ret = gpiochip_add_data(chip, gpio); in gpio_regmap_register()
278 if (config->irq_domain) { in gpio_regmap_register()
279 ret = gpiochip_irqchip_add_domain(chip, config->irq_domain); in gpio_regmap_register()
284 return gpio; in gpio_regmap_register()
289 kfree(gpio); in gpio_regmap_register()
295 * gpio_regmap_unregister() - Unregister a generic regmap GPIO controller
296 * @gpio: gpio_regmap device to unregister
298 void gpio_regmap_unregister(struct gpio_regmap *gpio) in gpio_regmap_unregister() argument
300 gpiochip_remove(&gpio->gpio_chip); in gpio_regmap_unregister()
301 kfree(gpio); in gpio_regmap_unregister()
311 * devm_gpio_regmap_register() - resource managed gpio_regmap_register()
312 * @dev: device that is registering this GPIO device
313 * @config: configuration for gpio_regmap
315 * Managed gpio_regmap_register(). For generic regmap GPIO device registered by
322 const struct gpio_regmap_config *config) in devm_gpio_regmap_register() argument
324 struct gpio_regmap *gpio; in devm_gpio_regmap_register() local
327 gpio = gpio_regmap_register(config); in devm_gpio_regmap_register()
329 if (IS_ERR(gpio)) in devm_gpio_regmap_register()
330 return gpio; in devm_gpio_regmap_register()
332 ret = devm_add_action_or_reset(dev, devm_gpio_regmap_unregister, gpio); in devm_gpio_regmap_register()
336 return gpio; in devm_gpio_regmap_register()
341 MODULE_DESCRIPTION("GPIO generic regmap driver core");