Lines Matching +full:gpio +full:- +full:dir

1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander
8 #include <linux/gpio/driver.h>
20 #include "pinctrl-utils.h"
54 * Pins availability is managed thanks to gpio-ranges property.
113 ret = regmap_read(pctl->stmfx->map, reg, &value); in stmfx_gpio_get()
124 regmap_write_bits(pctl->stmfx->map, reg + get_reg(offset), in stmfx_gpio_set()
136 ret = regmap_read(pctl->stmfx->map, reg, &val); in stmfx_gpio_get_direction()
138 * On stmfx, gpio pins direction is (0)input, (1)output. in stmfx_gpio_get_direction()
155 return regmap_write_bits(pctl->stmfx->map, reg, mask, 0); in stmfx_gpio_direction_input()
167 return regmap_write_bits(pctl->stmfx->map, reg, mask, mask); in stmfx_gpio_direction_output()
177 ret = regmap_read(pctl->stmfx->map, reg, &pupd); in stmfx_pinconf_get_pupd()
190 return regmap_write_bits(pctl->stmfx->map, reg, mask, pupd ? mask : 0); in stmfx_pinconf_set_pupd()
200 ret = regmap_read(pctl->stmfx->map, reg, &type); in stmfx_pinconf_get_type()
213 return regmap_write_bits(pctl->stmfx->map, reg, mask, type ? mask : 0); in stmfx_pinconf_set_type()
223 int ret, dir, type, pupd; in stmfx_pinconf_get() local
227 return -EINVAL; in stmfx_pinconf_get()
229 dir = stmfx_gpio_get_direction(&pctl->gpio_chip, pin); in stmfx_pinconf_get()
230 if (dir < 0) in stmfx_pinconf_get()
231 return dir; in stmfx_pinconf_get()
237 dir = (dir == GPIO_LINE_DIRECTION_IN) ? 1 : 0; in stmfx_pinconf_get()
248 if ((!dir && (!type || !pupd)) || (dir && !type)) in stmfx_pinconf_get()
252 if (dir && type && !pupd) in stmfx_pinconf_get()
260 if ((!dir && type) || (dir && !type)) in stmfx_pinconf_get()
264 if ((!dir && !type) || (dir && type)) in stmfx_pinconf_get()
268 if (dir) in stmfx_pinconf_get()
269 return -EINVAL; in stmfx_pinconf_get()
271 ret = stmfx_gpio_get(&pctl->gpio_chip, pin); in stmfx_pinconf_get()
278 return -ENOTSUPP; in stmfx_pinconf_get()
297 dev_err(pctldev->dev, "pin %d is not available\n", pin); in stmfx_pinconf_set()
298 return -EINVAL; in stmfx_pinconf_set()
335 ret = stmfx_gpio_direction_output(&pctl->gpio_chip, in stmfx_pinconf_set()
341 return -ENOTSUPP; in stmfx_pinconf_set()
353 int dir, type, pupd, val; in stmfx_pinconf_dbg_show() local
359 dir = stmfx_gpio_get_direction(&pctl->gpio_chip, offset); in stmfx_pinconf_dbg_show()
360 if (dir < 0) in stmfx_pinconf_dbg_show()
368 val = stmfx_gpio_get(&pctl->gpio_chip, offset); in stmfx_pinconf_dbg_show()
372 if (dir == GPIO_LINE_DIRECTION_OUT) { in stmfx_pinconf_dbg_show()
375 seq_printf(s, "open drain %s internal pull-up ", in stmfx_pinconf_dbg_show()
382 seq_printf(s, "with internal pull-%s ", in stmfx_pinconf_dbg_show()
411 return -ENOTSUPP; in stmfx_pinctrl_get_group_pins()
426 u32 reg = get_reg(data->hwirq); in stmfx_pinctrl_irq_mask()
427 u32 mask = get_mask(data->hwirq); in stmfx_pinctrl_irq_mask()
429 pctl->irq_gpi_src[reg] &= ~mask; in stmfx_pinctrl_irq_mask()
437 u32 reg = get_reg(data->hwirq); in stmfx_pinctrl_irq_unmask()
438 u32 mask = get_mask(data->hwirq); in stmfx_pinctrl_irq_unmask()
441 pctl->irq_gpi_src[reg] |= mask; in stmfx_pinctrl_irq_unmask()
448 u32 reg = get_reg(data->hwirq); in stmfx_pinctrl_irq_set_type()
449 u32 mask = get_mask(data->hwirq); in stmfx_pinctrl_irq_set_type()
452 return -EINVAL; in stmfx_pinctrl_irq_set_type()
455 pctl->irq_gpi_evt[reg] |= mask; in stmfx_pinctrl_irq_set_type()
458 pctl->irq_gpi_evt[reg] &= ~mask; in stmfx_pinctrl_irq_set_type()
463 pctl->irq_gpi_type[reg] |= mask; in stmfx_pinctrl_irq_set_type()
465 pctl->irq_gpi_type[reg] &= ~mask; in stmfx_pinctrl_irq_set_type()
469 * GPIO value to set the right edge trigger. But in atomic context in stmfx_pinctrl_irq_set_type()
475 pctl->irq_toggle_edge[reg] |= mask; in stmfx_pinctrl_irq_set_type()
477 pctl->irq_toggle_edge[reg] &= mask; in stmfx_pinctrl_irq_set_type()
487 mutex_lock(&pctl->lock); in stmfx_pinctrl_irq_bus_lock()
494 u32 reg = get_reg(data->hwirq); in stmfx_pinctrl_irq_bus_sync_unlock()
495 u32 mask = get_mask(data->hwirq); in stmfx_pinctrl_irq_bus_sync_unlock()
498 * In case of IRQ_TYPE_EDGE_BOTH), read the current GPIO value in stmfx_pinctrl_irq_bus_sync_unlock()
502 if (pctl->irq_toggle_edge[reg] & mask) { in stmfx_pinctrl_irq_bus_sync_unlock()
503 if (stmfx_gpio_get(gpio_chip, data->hwirq)) in stmfx_pinctrl_irq_bus_sync_unlock()
504 pctl->irq_gpi_type[reg] &= ~mask; in stmfx_pinctrl_irq_bus_sync_unlock()
506 pctl->irq_gpi_type[reg] |= mask; in stmfx_pinctrl_irq_bus_sync_unlock()
509 regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_EVT, in stmfx_pinctrl_irq_bus_sync_unlock()
510 pctl->irq_gpi_evt, NR_GPIO_REGS); in stmfx_pinctrl_irq_bus_sync_unlock()
511 regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_TYPE, in stmfx_pinctrl_irq_bus_sync_unlock()
512 pctl->irq_gpi_type, NR_GPIO_REGS); in stmfx_pinctrl_irq_bus_sync_unlock()
513 regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, in stmfx_pinctrl_irq_bus_sync_unlock()
514 pctl->irq_gpi_src, NR_GPIO_REGS); in stmfx_pinctrl_irq_bus_sync_unlock()
516 mutex_unlock(&pctl->lock); in stmfx_pinctrl_irq_bus_sync_unlock()
524 ret = stmfx_gpio_direction_input(gpio_chip, data->hwirq); in stmfx_gpio_irq_request_resources()
528 return gpiochip_reqres_irq(gpio_chip, data->hwirq); in stmfx_gpio_irq_request_resources()
535 return gpiochip_relres_irq(gpio_chip, data->hwirq); in stmfx_gpio_irq_release_resources()
545 if (!(pctl->irq_toggle_edge[reg] & mask)) in stmfx_pinctrl_irq_toggle_trigger()
548 val = stmfx_gpio_get(&pctl->gpio_chip, offset); in stmfx_pinctrl_irq_toggle_trigger()
553 pctl->irq_gpi_type[reg] &= mask; in stmfx_pinctrl_irq_toggle_trigger()
554 regmap_write_bits(pctl->stmfx->map, in stmfx_pinctrl_irq_toggle_trigger()
559 pctl->irq_gpi_type[reg] |= mask; in stmfx_pinctrl_irq_toggle_trigger()
560 regmap_write_bits(pctl->stmfx->map, in stmfx_pinctrl_irq_toggle_trigger()
569 struct gpio_chip *gc = &pctl->gpio_chip; in stmfx_pinctrl_irq_thread_fn()
575 ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_IRQ_GPI_PENDING, in stmfx_pinctrl_irq_thread_fn()
580 regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, in stmfx_pinctrl_irq_thread_fn()
586 for_each_set_bit(n, &status, gc->ngpio) { in stmfx_pinctrl_irq_thread_fn()
587 handle_nested_irq(irq_find_mapping(gc->irq.domain, n)); in stmfx_pinctrl_irq_thread_fn()
591 regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, in stmfx_pinctrl_irq_thread_fn()
592 pctl->irq_gpi_src, NR_GPIO_REGS); in stmfx_pinctrl_irq_thread_fn()
602 seq_printf(p, dev_name(pctl->dev)); in stmfx_pinctrl_irq_print_chip()
620 struct pinctrl_dev *pctl_dev = pctl->pctl_dev; in stmfx_pinctrl_gpio_function_enable()
623 pctl->gpio_valid_mask = GENMASK(15, 0); in stmfx_pinctrl_gpio_function_enable()
628 pctl->gpio_valid_mask |= GENMASK(19, 16); in stmfx_pinctrl_gpio_function_enable()
634 pctl->gpio_valid_mask |= GENMASK(23, 20); in stmfx_pinctrl_gpio_function_enable()
637 return stmfx_function_enable(pctl->stmfx, func); in stmfx_pinctrl_gpio_function_enable()
642 struct stmfx *stmfx = dev_get_drvdata(pdev->dev.parent); in stmfx_pinctrl_probe()
643 struct device_node *np = pdev->dev.of_node; in stmfx_pinctrl_probe()
648 pctl = devm_kzalloc(stmfx->dev, sizeof(*pctl), GFP_KERNEL); in stmfx_pinctrl_probe()
650 return -ENOMEM; in stmfx_pinctrl_probe()
654 pctl->dev = &pdev->dev; in stmfx_pinctrl_probe()
655 pctl->stmfx = stmfx; in stmfx_pinctrl_probe()
657 if (!of_property_present(np, "gpio-ranges")) { in stmfx_pinctrl_probe()
658 dev_err(pctl->dev, "missing required gpio-ranges property\n"); in stmfx_pinctrl_probe()
659 return -EINVAL; in stmfx_pinctrl_probe()
666 mutex_init(&pctl->lock); in stmfx_pinctrl_probe()
669 pctl->pctl_desc.name = "stmfx-pinctrl"; in stmfx_pinctrl_probe()
670 pctl->pctl_desc.pctlops = &stmfx_pinctrl_ops; in stmfx_pinctrl_probe()
671 pctl->pctl_desc.confops = &stmfx_pinconf_ops; in stmfx_pinctrl_probe()
672 pctl->pctl_desc.pins = stmfx_pins; in stmfx_pinctrl_probe()
673 pctl->pctl_desc.npins = ARRAY_SIZE(stmfx_pins); in stmfx_pinctrl_probe()
674 pctl->pctl_desc.owner = THIS_MODULE; in stmfx_pinctrl_probe()
675 pctl->pctl_desc.link_consumers = true; in stmfx_pinctrl_probe()
677 ret = devm_pinctrl_register_and_init(pctl->dev, &pctl->pctl_desc, in stmfx_pinctrl_probe()
678 pctl, &pctl->pctl_dev); in stmfx_pinctrl_probe()
680 dev_err(pctl->dev, "pinctrl registration failed\n"); in stmfx_pinctrl_probe()
684 ret = pinctrl_enable(pctl->pctl_dev); in stmfx_pinctrl_probe()
686 dev_err(pctl->dev, "pinctrl enable failed\n"); in stmfx_pinctrl_probe()
690 /* Register gpio controller */ in stmfx_pinctrl_probe()
691 pctl->gpio_chip.label = "stmfx-gpio"; in stmfx_pinctrl_probe()
692 pctl->gpio_chip.parent = pctl->dev; in stmfx_pinctrl_probe()
693 pctl->gpio_chip.get_direction = stmfx_gpio_get_direction; in stmfx_pinctrl_probe()
694 pctl->gpio_chip.direction_input = stmfx_gpio_direction_input; in stmfx_pinctrl_probe()
695 pctl->gpio_chip.direction_output = stmfx_gpio_direction_output; in stmfx_pinctrl_probe()
696 pctl->gpio_chip.get = stmfx_gpio_get; in stmfx_pinctrl_probe()
697 pctl->gpio_chip.set = stmfx_gpio_set; in stmfx_pinctrl_probe()
698 pctl->gpio_chip.set_config = gpiochip_generic_config; in stmfx_pinctrl_probe()
699 pctl->gpio_chip.base = -1; in stmfx_pinctrl_probe()
700 pctl->gpio_chip.ngpio = pctl->pctl_desc.npins; in stmfx_pinctrl_probe()
701 pctl->gpio_chip.can_sleep = true; in stmfx_pinctrl_probe()
703 girq = &pctl->gpio_chip.irq; in stmfx_pinctrl_probe()
706 girq->parent_handler = NULL; in stmfx_pinctrl_probe()
707 girq->num_parents = 0; in stmfx_pinctrl_probe()
708 girq->parents = NULL; in stmfx_pinctrl_probe()
709 girq->default_type = IRQ_TYPE_NONE; in stmfx_pinctrl_probe()
710 girq->handler = handle_bad_irq; in stmfx_pinctrl_probe()
711 girq->threaded = true; in stmfx_pinctrl_probe()
713 ret = devm_gpiochip_add_data(pctl->dev, &pctl->gpio_chip, pctl); in stmfx_pinctrl_probe()
715 dev_err(pctl->dev, "gpio_chip registration failed\n"); in stmfx_pinctrl_probe()
723 ret = devm_request_threaded_irq(pctl->dev, irq, NULL, in stmfx_pinctrl_probe()
726 dev_name(pctl->dev), pctl); in stmfx_pinctrl_probe()
728 dev_err(pctl->dev, "cannot request irq%d\n", irq); in stmfx_pinctrl_probe()
732 dev_info(pctl->dev, in stmfx_pinctrl_probe()
733 "%ld GPIOs available\n", hweight_long(pctl->gpio_valid_mask)); in stmfx_pinctrl_probe()
740 struct stmfx *stmfx = dev_get_drvdata(pdev->dev.parent); in stmfx_pinctrl_remove()
748 dev_err(&pdev->dev, "Failed to disable pins (%pe)\n", in stmfx_pinctrl_remove()
757 ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_GPIO_STATE, in stmfx_pinctrl_backup_regs()
758 &pctl->bkp_gpio_state, NR_GPIO_REGS); in stmfx_pinctrl_backup_regs()
761 ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_GPIO_DIR, in stmfx_pinctrl_backup_regs()
762 &pctl->bkp_gpio_dir, NR_GPIO_REGS); in stmfx_pinctrl_backup_regs()
765 ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_GPIO_TYPE, in stmfx_pinctrl_backup_regs()
766 &pctl->bkp_gpio_type, NR_GPIO_REGS); in stmfx_pinctrl_backup_regs()
769 ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_GPIO_PUPD, in stmfx_pinctrl_backup_regs()
770 &pctl->bkp_gpio_pupd, NR_GPIO_REGS); in stmfx_pinctrl_backup_regs()
781 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_GPIO_DIR, in stmfx_pinctrl_restore_regs()
782 pctl->bkp_gpio_dir, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
785 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_GPIO_TYPE, in stmfx_pinctrl_restore_regs()
786 pctl->bkp_gpio_type, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
789 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_GPIO_PUPD, in stmfx_pinctrl_restore_regs()
790 pctl->bkp_gpio_pupd, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
793 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_GPO_SET, in stmfx_pinctrl_restore_regs()
794 pctl->bkp_gpio_state, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
797 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_EVT, in stmfx_pinctrl_restore_regs()
798 pctl->irq_gpi_evt, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
801 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_TYPE, in stmfx_pinctrl_restore_regs()
802 pctl->irq_gpi_type, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
805 ret = regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, in stmfx_pinctrl_restore_regs()
806 pctl->irq_gpi_src, NR_GPIO_REGS); in stmfx_pinctrl_restore_regs()
820 dev_err(pctl->dev, "registers backup failure\n"); in stmfx_pinctrl_suspend()
834 dev_err(pctl->dev, "registers restoration failure\n"); in stmfx_pinctrl_resume()
846 { .compatible = "st,stmfx-0300-pinctrl", },
853 .name = "stmfx-pinctrl",
862 MODULE_DESCRIPTION("STMFX pinctrl/GPIO driver");