Lines Matching +full:int +full:- +full:map +full:- +full:mask
1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander
19 #include "pinctrl-utils.h"
53 * Pins availability is managed thanks to gpio-ranges property.
104 static int stmfx_gpio_get(struct gpio_chip *gc, unsigned int offset) in stmfx_gpio_get()
108 u32 mask = get_mask(offset); in stmfx_gpio_get() local
110 int ret; in stmfx_gpio_get()
112 ret = regmap_read(pctl->stmfx->map, reg, &value); in stmfx_gpio_get()
114 return ret ? ret : !!(value & mask); in stmfx_gpio_get()
117 static void stmfx_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) in stmfx_gpio_set()
121 u32 mask = get_mask(offset); in stmfx_gpio_set() local
123 regmap_write_bits(pctl->stmfx->map, reg + get_reg(offset), in stmfx_gpio_set()
124 mask, mask); in stmfx_gpio_set()
127 static int stmfx_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) in stmfx_gpio_get_direction()
131 u32 mask = get_mask(offset); in stmfx_gpio_get_direction() local
133 int ret; in stmfx_gpio_get_direction()
135 ret = regmap_read(pctl->stmfx->map, reg, &val); in stmfx_gpio_get_direction()
142 if (val & mask) in stmfx_gpio_get_direction()
148 static int stmfx_gpio_direction_input(struct gpio_chip *gc, unsigned int offset) in stmfx_gpio_direction_input()
152 u32 mask = get_mask(offset); in stmfx_gpio_direction_input() local
154 return regmap_write_bits(pctl->stmfx->map, reg, mask, 0); in stmfx_gpio_direction_input()
157 static int stmfx_gpio_direction_output(struct gpio_chip *gc, in stmfx_gpio_direction_output()
158 unsigned int offset, int value) in stmfx_gpio_direction_output()
162 u32 mask = get_mask(offset); in stmfx_gpio_direction_output() local
166 return regmap_write_bits(pctl->stmfx->map, reg, mask, mask); in stmfx_gpio_direction_output()
169 static int stmfx_pinconf_get_pupd(struct stmfx_pinctrl *pctl, in stmfx_pinconf_get_pupd()
170 unsigned int offset) in stmfx_pinconf_get_pupd()
173 u32 pupd, mask = get_mask(offset); in stmfx_pinconf_get_pupd() local
174 int ret; in stmfx_pinconf_get_pupd()
176 ret = regmap_read(pctl->stmfx->map, reg, &pupd); in stmfx_pinconf_get_pupd()
180 return !!(pupd & mask); in stmfx_pinconf_get_pupd()
183 static int stmfx_pinconf_set_pupd(struct stmfx_pinctrl *pctl, in stmfx_pinconf_set_pupd()
184 unsigned int offset, u32 pupd) in stmfx_pinconf_set_pupd()
187 u32 mask = get_mask(offset); in stmfx_pinconf_set_pupd() local
189 return regmap_write_bits(pctl->stmfx->map, reg, mask, pupd ? mask : 0); in stmfx_pinconf_set_pupd()
192 static int stmfx_pinconf_get_type(struct stmfx_pinctrl *pctl, in stmfx_pinconf_get_type()
193 unsigned int offset) in stmfx_pinconf_get_type()
196 u32 type, mask = get_mask(offset); in stmfx_pinconf_get_type() local
197 int ret; in stmfx_pinconf_get_type()
199 ret = regmap_read(pctl->stmfx->map, reg, &type); in stmfx_pinconf_get_type()
203 return !!(type & mask); in stmfx_pinconf_get_type()
206 static int stmfx_pinconf_set_type(struct stmfx_pinctrl *pctl, in stmfx_pinconf_set_type()
207 unsigned int offset, u32 type) in stmfx_pinconf_set_type()
210 u32 mask = get_mask(offset); in stmfx_pinconf_set_type() local
212 return regmap_write_bits(pctl->stmfx->map, reg, mask, type ? mask : 0); in stmfx_pinconf_set_type()
215 static int stmfx_pinconf_get(struct pinctrl_dev *pctldev, in stmfx_pinconf_get()
216 unsigned int pin, unsigned long *config) in stmfx_pinconf_get()
222 int ret, dir, type, pupd; in stmfx_pinconf_get()
226 return -EINVAL; in stmfx_pinconf_get()
228 dir = stmfx_gpio_get_direction(&pctl->gpio_chip, pin); in stmfx_pinconf_get()
268 return -EINVAL; in stmfx_pinconf_get()
270 ret = stmfx_gpio_get(&pctl->gpio_chip, pin); in stmfx_pinconf_get()
277 return -ENOTSUPP; in stmfx_pinconf_get()
285 static int stmfx_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, in stmfx_pinconf_set()
286 unsigned long *configs, unsigned int num_configs) in stmfx_pinconf_set()
292 int i, ret; in stmfx_pinconf_set()
296 dev_err(pctldev->dev, "pin %d is not available\n", pin); in stmfx_pinconf_set()
297 return -EINVAL; in stmfx_pinconf_set()
334 ret = stmfx_gpio_direction_output(&pctl->gpio_chip, in stmfx_pinconf_set()
340 return -ENOTSUPP; in stmfx_pinconf_set()
348 struct seq_file *s, unsigned int offset) in stmfx_pinconf_dbg_show()
352 int dir, type, pupd, val; in stmfx_pinconf_dbg_show()
358 dir = stmfx_gpio_get_direction(&pctl->gpio_chip, offset); in stmfx_pinconf_dbg_show()
367 val = stmfx_gpio_get(&pctl->gpio_chip, offset); in stmfx_pinconf_dbg_show()
374 seq_printf(s, "open drain %s internal pull-up ", in stmfx_pinconf_dbg_show()
381 seq_printf(s, "with internal pull-%s ", in stmfx_pinconf_dbg_show()
394 static int stmfx_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) in stmfx_pinctrl_get_groups_count()
400 unsigned int selector) in stmfx_pinctrl_get_group_name()
405 static int stmfx_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, in stmfx_pinctrl_get_group_pins()
406 unsigned int selector, in stmfx_pinctrl_get_group_pins()
407 const unsigned int **pins, in stmfx_pinctrl_get_group_pins()
408 unsigned int *num_pins) in stmfx_pinctrl_get_group_pins()
410 return -ENOTSUPP; in stmfx_pinctrl_get_group_pins()
425 u32 reg = get_reg(data->hwirq); in stmfx_pinctrl_irq_mask()
426 u32 mask = get_mask(data->hwirq); in stmfx_pinctrl_irq_mask() local
428 pctl->irq_gpi_src[reg] &= ~mask; in stmfx_pinctrl_irq_mask()
436 u32 reg = get_reg(data->hwirq); in stmfx_pinctrl_irq_unmask()
437 u32 mask = get_mask(data->hwirq); in stmfx_pinctrl_irq_unmask() local
440 pctl->irq_gpi_src[reg] |= mask; in stmfx_pinctrl_irq_unmask()
443 static int stmfx_pinctrl_irq_set_type(struct irq_data *data, unsigned int type) in stmfx_pinctrl_irq_set_type()
447 u32 reg = get_reg(data->hwirq); in stmfx_pinctrl_irq_set_type()
448 u32 mask = get_mask(data->hwirq); in stmfx_pinctrl_irq_set_type() local
451 return -EINVAL; in stmfx_pinctrl_irq_set_type()
454 pctl->irq_gpi_evt[reg] |= mask; in stmfx_pinctrl_irq_set_type()
457 pctl->irq_gpi_evt[reg] &= ~mask; in stmfx_pinctrl_irq_set_type()
462 pctl->irq_gpi_type[reg] |= mask; in stmfx_pinctrl_irq_set_type()
464 pctl->irq_gpi_type[reg] &= ~mask; in stmfx_pinctrl_irq_set_type()
474 pctl->irq_toggle_edge[reg] |= mask; in stmfx_pinctrl_irq_set_type()
476 pctl->irq_toggle_edge[reg] &= mask; in stmfx_pinctrl_irq_set_type()
486 mutex_lock(&pctl->lock); in stmfx_pinctrl_irq_bus_lock()
493 u32 reg = get_reg(data->hwirq); in stmfx_pinctrl_irq_bus_sync_unlock()
494 u32 mask = get_mask(data->hwirq); in stmfx_pinctrl_irq_bus_sync_unlock() local
501 if (pctl->irq_toggle_edge[reg] & mask) { in stmfx_pinctrl_irq_bus_sync_unlock()
502 if (stmfx_gpio_get(gpio_chip, data->hwirq)) in stmfx_pinctrl_irq_bus_sync_unlock()
503 pctl->irq_gpi_type[reg] &= ~mask; in stmfx_pinctrl_irq_bus_sync_unlock()
505 pctl->irq_gpi_type[reg] |= mask; in stmfx_pinctrl_irq_bus_sync_unlock()
508 regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_EVT, in stmfx_pinctrl_irq_bus_sync_unlock()
509 pctl->irq_gpi_evt, NR_GPIO_REGS); in stmfx_pinctrl_irq_bus_sync_unlock()
510 regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_TYPE, in stmfx_pinctrl_irq_bus_sync_unlock()
511 pctl->irq_gpi_type, NR_GPIO_REGS); in stmfx_pinctrl_irq_bus_sync_unlock()
512 regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, in stmfx_pinctrl_irq_bus_sync_unlock()
513 pctl->irq_gpi_src, NR_GPIO_REGS); in stmfx_pinctrl_irq_bus_sync_unlock()
515 mutex_unlock(&pctl->lock); in stmfx_pinctrl_irq_bus_sync_unlock()
518 static int stmfx_gpio_irq_request_resources(struct irq_data *data) in stmfx_gpio_irq_request_resources()
521 int ret; in stmfx_gpio_irq_request_resources()
523 ret = stmfx_gpio_direction_input(gpio_chip, data->hwirq); in stmfx_gpio_irq_request_resources()
527 return gpiochip_reqres_irq(gpio_chip, data->hwirq); in stmfx_gpio_irq_request_resources()
534 return gpiochip_relres_irq(gpio_chip, data->hwirq); in stmfx_gpio_irq_release_resources()
538 unsigned int offset) in stmfx_pinctrl_irq_toggle_trigger()
541 u32 mask = get_mask(offset); in stmfx_pinctrl_irq_toggle_trigger() local
542 int val; in stmfx_pinctrl_irq_toggle_trigger()
544 if (!(pctl->irq_toggle_edge[reg] & mask)) in stmfx_pinctrl_irq_toggle_trigger()
547 val = stmfx_gpio_get(&pctl->gpio_chip, offset); in stmfx_pinctrl_irq_toggle_trigger()
552 pctl->irq_gpi_type[reg] &= mask; in stmfx_pinctrl_irq_toggle_trigger()
553 regmap_write_bits(pctl->stmfx->map, in stmfx_pinctrl_irq_toggle_trigger()
555 mask, 0); in stmfx_pinctrl_irq_toggle_trigger()
558 pctl->irq_gpi_type[reg] |= mask; in stmfx_pinctrl_irq_toggle_trigger()
559 regmap_write_bits(pctl->stmfx->map, in stmfx_pinctrl_irq_toggle_trigger()
561 mask, mask); in stmfx_pinctrl_irq_toggle_trigger()
565 static irqreturn_t stmfx_pinctrl_irq_thread_fn(int irq, void *dev_id) in stmfx_pinctrl_irq_thread_fn()
568 struct gpio_chip *gc = &pctl->gpio_chip; in stmfx_pinctrl_irq_thread_fn()
572 int i, ret; in stmfx_pinctrl_irq_thread_fn()
574 ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_IRQ_GPI_PENDING, in stmfx_pinctrl_irq_thread_fn()
579 regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, in stmfx_pinctrl_irq_thread_fn()
585 for_each_set_bit(n, &status, gc->ngpio) { in stmfx_pinctrl_irq_thread_fn()
586 handle_nested_irq(irq_find_mapping(gc->irq.domain, n)); in stmfx_pinctrl_irq_thread_fn()
590 regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, in stmfx_pinctrl_irq_thread_fn()
591 pctl->irq_gpi_src, NR_GPIO_REGS); in stmfx_pinctrl_irq_thread_fn()
601 seq_printf(p, dev_name(pctl->dev)); in stmfx_pinctrl_irq_print_chip()
616 static int stmfx_pinctrl_gpio_function_enable(struct stmfx_pinctrl *pctl) in stmfx_pinctrl_gpio_function_enable()
619 struct pinctrl_dev *pctl_dev = pctl->pctl_dev; in stmfx_pinctrl_gpio_function_enable()
622 pctl->gpio_valid_mask = GENMASK(15, 0); in stmfx_pinctrl_gpio_function_enable()
627 pctl->gpio_valid_mask |= GENMASK(19, 16); in stmfx_pinctrl_gpio_function_enable()
633 pctl->gpio_valid_mask |= GENMASK(23, 20); in stmfx_pinctrl_gpio_function_enable()
636 return stmfx_function_enable(pctl->stmfx, func); in stmfx_pinctrl_gpio_function_enable()
639 static int stmfx_pinctrl_probe(struct platform_device *pdev) in stmfx_pinctrl_probe()
641 struct stmfx *stmfx = dev_get_drvdata(pdev->dev.parent); in stmfx_pinctrl_probe()
642 struct device_node *np = pdev->dev.of_node; in stmfx_pinctrl_probe()
645 int irq, ret; in stmfx_pinctrl_probe()
647 pctl = devm_kzalloc(stmfx->dev, sizeof(*pctl), GFP_KERNEL); in stmfx_pinctrl_probe()
649 return -ENOMEM; in stmfx_pinctrl_probe()
653 pctl->dev = &pdev->dev; in stmfx_pinctrl_probe()
654 pctl->stmfx = stmfx; in stmfx_pinctrl_probe()
656 if (!of_property_present(np, "gpio-ranges")) { in stmfx_pinctrl_probe()
657 dev_err(pctl->dev, "missing required gpio-ranges property\n"); in stmfx_pinctrl_probe()
658 return -EINVAL; in stmfx_pinctrl_probe()
665 mutex_init(&pctl->lock); in stmfx_pinctrl_probe()
668 pctl->pctl_desc.name = "stmfx-pinctrl"; in stmfx_pinctrl_probe()
669 pctl->pctl_desc.pctlops = &stmfx_pinctrl_ops; in stmfx_pinctrl_probe()
670 pctl->pctl_desc.confops = &stmfx_pinconf_ops; in stmfx_pinctrl_probe()
671 pctl->pctl_desc.pins = stmfx_pins; in stmfx_pinctrl_probe()
672 pctl->pctl_desc.npins = ARRAY_SIZE(stmfx_pins); in stmfx_pinctrl_probe()
673 pctl->pctl_desc.owner = THIS_MODULE; in stmfx_pinctrl_probe()
674 pctl->pctl_desc.link_consumers = true; in stmfx_pinctrl_probe()
676 ret = devm_pinctrl_register_and_init(pctl->dev, &pctl->pctl_desc, in stmfx_pinctrl_probe()
677 pctl, &pctl->pctl_dev); in stmfx_pinctrl_probe()
679 dev_err(pctl->dev, "pinctrl registration failed\n"); in stmfx_pinctrl_probe()
683 ret = pinctrl_enable(pctl->pctl_dev); in stmfx_pinctrl_probe()
685 dev_err(pctl->dev, "pinctrl enable failed\n"); in stmfx_pinctrl_probe()
690 pctl->gpio_chip.label = "stmfx-gpio"; in stmfx_pinctrl_probe()
691 pctl->gpio_chip.parent = pctl->dev; in stmfx_pinctrl_probe()
692 pctl->gpio_chip.get_direction = stmfx_gpio_get_direction; in stmfx_pinctrl_probe()
693 pctl->gpio_chip.direction_input = stmfx_gpio_direction_input; in stmfx_pinctrl_probe()
694 pctl->gpio_chip.direction_output = stmfx_gpio_direction_output; in stmfx_pinctrl_probe()
695 pctl->gpio_chip.get = stmfx_gpio_get; in stmfx_pinctrl_probe()
696 pctl->gpio_chip.set = stmfx_gpio_set; in stmfx_pinctrl_probe()
697 pctl->gpio_chip.set_config = gpiochip_generic_config; in stmfx_pinctrl_probe()
698 pctl->gpio_chip.base = -1; in stmfx_pinctrl_probe()
699 pctl->gpio_chip.ngpio = pctl->pctl_desc.npins; in stmfx_pinctrl_probe()
700 pctl->gpio_chip.can_sleep = true; in stmfx_pinctrl_probe()
702 girq = &pctl->gpio_chip.irq; in stmfx_pinctrl_probe()
705 girq->parent_handler = NULL; in stmfx_pinctrl_probe()
706 girq->num_parents = 0; in stmfx_pinctrl_probe()
707 girq->parents = NULL; in stmfx_pinctrl_probe()
708 girq->default_type = IRQ_TYPE_NONE; in stmfx_pinctrl_probe()
709 girq->handler = handle_bad_irq; in stmfx_pinctrl_probe()
710 girq->threaded = true; in stmfx_pinctrl_probe()
712 ret = devm_gpiochip_add_data(pctl->dev, &pctl->gpio_chip, pctl); in stmfx_pinctrl_probe()
714 dev_err(pctl->dev, "gpio_chip registration failed\n"); in stmfx_pinctrl_probe()
722 ret = devm_request_threaded_irq(pctl->dev, irq, NULL, in stmfx_pinctrl_probe()
725 dev_name(pctl->dev), pctl); in stmfx_pinctrl_probe()
727 dev_err(pctl->dev, "cannot request irq%d\n", irq); in stmfx_pinctrl_probe()
731 dev_info(pctl->dev, in stmfx_pinctrl_probe()
732 "%ld GPIOs available\n", hweight_long(pctl->gpio_valid_mask)); in stmfx_pinctrl_probe()
737 static int stmfx_pinctrl_remove(struct platform_device *pdev) in stmfx_pinctrl_remove()
739 struct stmfx *stmfx = dev_get_drvdata(pdev->dev.parent); in stmfx_pinctrl_remove()
748 static int stmfx_pinctrl_backup_regs(struct stmfx_pinctrl *pctl) in stmfx_pinctrl_backup_regs()
750 int ret; in stmfx_pinctrl_backup_regs()
752 ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_GPIO_STATE, in stmfx_pinctrl_backup_regs()
753 &pctl->bkp_gpio_state, NR_GPIO_REGS); in stmfx_pinctrl_backup_regs()
756 ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_GPIO_DIR, in stmfx_pinctrl_backup_regs()
757 &pctl->bkp_gpio_dir, NR_GPIO_REGS); in stmfx_pinctrl_backup_regs()
760 ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_GPIO_TYPE, in stmfx_pinctrl_backup_regs()
761 &pctl->bkp_gpio_type, NR_GPIO_REGS); in stmfx_pinctrl_backup_regs()
764 ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_GPIO_PUPD, in stmfx_pinctrl_backup_regs()
765 &pctl->bkp_gpio_pupd, NR_GPIO_REGS); in stmfx_pinctrl_backup_regs()
772 static int stmfx_pinctrl_restore_regs(struct stmfx_pinctrl *pctl) in stmfx_pinctrl_restore_regs()
774 int ret; in stmfx_pinctrl_restore_regs()
776 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_GPIO_DIR, in stmfx_pinctrl_restore_regs()
777 pctl->bkp_gpio_dir, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
780 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_GPIO_TYPE, in stmfx_pinctrl_restore_regs()
781 pctl->bkp_gpio_type, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
784 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_GPIO_PUPD, in stmfx_pinctrl_restore_regs()
785 pctl->bkp_gpio_pupd, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
788 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_GPO_SET, in stmfx_pinctrl_restore_regs()
789 pctl->bkp_gpio_state, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
792 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_EVT, in stmfx_pinctrl_restore_regs()
793 pctl->irq_gpi_evt, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
796 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_TYPE, in stmfx_pinctrl_restore_regs()
797 pctl->irq_gpi_type, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
800 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, in stmfx_pinctrl_restore_regs()
801 pctl->irq_gpi_src, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
808 static int stmfx_pinctrl_suspend(struct device *dev) in stmfx_pinctrl_suspend()
811 int ret; in stmfx_pinctrl_suspend()
815 dev_err(pctl->dev, "registers backup failure\n"); in stmfx_pinctrl_suspend()
822 static int stmfx_pinctrl_resume(struct device *dev) in stmfx_pinctrl_resume()
825 int ret; in stmfx_pinctrl_resume()
829 dev_err(pctl->dev, "registers restoration failure\n"); in stmfx_pinctrl_resume()
841 { .compatible = "st,stmfx-0300-pinctrl", },
848 .name = "stmfx-pinctrl",