Lines Matching +full:gpio +full:- +full:width
1 // SPDX-License-Identifier: GPL-2.0+
6 * Author: David Liu <liuwei@actions-semi.com>
14 #include <linux/gpio/driver.h>
25 #include <linux/pinctrl/pinconf-generic.h>
31 #include "../pinctrl-utils.h"
32 #include "pinctrl-owl.h"
35 * struct owl_pinctrl - pinctrl state of the device
38 * @chip: gpio chip
70 u32 bit, u32 width) in owl_read_field() argument
74 tmp = readl_relaxed(pctrl->base + reg); in owl_read_field()
75 mask = (1 << width) - 1; in owl_read_field()
81 u32 bit, u32 width) in owl_write_field() argument
85 mask = (1 << width) - 1; in owl_write_field()
88 owl_update_bits(pctrl->base + reg, mask, (arg << bit)); in owl_write_field()
95 return pctrl->soc->ngroups; in owl_get_groups_count()
103 return pctrl->soc->groups[group].name; in owl_get_group_name()
113 *pins = pctrl->soc->groups[group].pads; in owl_get_group_pins()
114 *num_pins = pctrl->soc->groups[group].npads; in owl_get_group_pins()
125 seq_printf(s, "%s", dev_name(pctrl->dev)); in owl_pin_dbg_show()
141 return pctrl->soc->nfunctions; in owl_get_funcs_count()
149 return pctrl->soc->functions[function].name; in owl_get_func_name()
159 *groups = pctrl->soc->functions[function].groups; in owl_get_func_groups()
160 *num_groups = pctrl->soc->functions[function].ngroups; in owl_get_func_groups()
174 for (id = 0; id < g->nfuncs; id++) { in get_group_mfp_mask_val()
175 if (g->funcs[id] == function) in get_group_mfp_mask_val()
178 if (WARN_ON(id == g->nfuncs)) in get_group_mfp_mask_val()
179 return -EINVAL; in get_group_mfp_mask_val()
181 option_num = (1 << g->mfpctl_width); in get_group_mfp_mask_val()
183 id -= option_num; in get_group_mfp_mask_val()
185 option_mask = option_num - 1; in get_group_mfp_mask_val()
186 *mask = (option_mask << g->mfpctl_shift); in get_group_mfp_mask_val()
187 *val = (id << g->mfpctl_shift); in get_group_mfp_mask_val()
201 g = &pctrl->soc->groups[group]; in owl_set_mux()
204 return -EINVAL; in owl_set_mux()
206 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_set_mux()
208 owl_update_bits(pctrl->base + g->mfpctl_reg, mask, val); in owl_set_mux()
210 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_set_mux()
226 u32 *width) in owl_pad_pinconf_reg() argument
233 if (!info->pullctl) in owl_pad_pinconf_reg()
234 return -EINVAL; in owl_pad_pinconf_reg()
235 *reg = info->pullctl->reg; in owl_pad_pinconf_reg()
236 *bit = info->pullctl->shift; in owl_pad_pinconf_reg()
237 *width = info->pullctl->width; in owl_pad_pinconf_reg()
240 if (!info->st) in owl_pad_pinconf_reg()
241 return -EINVAL; in owl_pad_pinconf_reg()
242 *reg = info->st->reg; in owl_pad_pinconf_reg()
243 *bit = info->st->shift; in owl_pad_pinconf_reg()
244 *width = info->st->width; in owl_pad_pinconf_reg()
247 return -ENOTSUPP; in owl_pad_pinconf_reg()
261 u32 reg, bit, width, arg; in owl_pin_config_get() local
263 info = &pctrl->soc->padinfo[pin]; in owl_pin_config_get()
265 ret = owl_pad_pinconf_reg(info, param, ®, &bit, &width); in owl_pin_config_get()
269 arg = owl_read_field(pctrl, reg, bit, width); in owl_pin_config_get()
271 if (!pctrl->soc->padctl_val2arg) in owl_pin_config_get()
272 return -ENOTSUPP; in owl_pin_config_get()
274 ret = pctrl->soc->padctl_val2arg(info, param, &arg); in owl_pin_config_get()
292 u32 reg, bit, width, arg; in owl_pin_config_set() local
295 info = &pctrl->soc->padinfo[pin]; in owl_pin_config_set()
301 ret = owl_pad_pinconf_reg(info, param, ®, &bit, &width); in owl_pin_config_set()
305 if (!pctrl->soc->padctl_arg2val) in owl_pin_config_set()
306 return -ENOTSUPP; in owl_pin_config_set()
308 ret = pctrl->soc->padctl_arg2val(info, param, &arg); in owl_pin_config_set()
312 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_pin_config_set()
314 owl_write_field(pctrl, reg, arg, bit, width); in owl_pin_config_set()
316 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_pin_config_set()
326 u32 *width) in owl_group_pinconf_reg() argument
330 if (g->drv_reg < 0) in owl_group_pinconf_reg()
331 return -EINVAL; in owl_group_pinconf_reg()
332 *reg = g->drv_reg; in owl_group_pinconf_reg()
333 *bit = g->drv_shift; in owl_group_pinconf_reg()
334 *width = g->drv_width; in owl_group_pinconf_reg()
337 if (g->sr_reg < 0) in owl_group_pinconf_reg()
338 return -EINVAL; in owl_group_pinconf_reg()
339 *reg = g->sr_reg; in owl_group_pinconf_reg()
340 *bit = g->sr_shift; in owl_group_pinconf_reg()
341 *width = g->sr_width; in owl_group_pinconf_reg()
344 return -ENOTSUPP; in owl_group_pinconf_reg()
370 return -EINVAL; in owl_group_pinconf_arg2val()
380 return -ENOTSUPP; in owl_group_pinconf_arg2val()
406 return -EINVAL; in owl_group_pinconf_val2arg()
416 return -ENOTSUPP; in owl_group_pinconf_val2arg()
429 u32 reg, bit, width, arg; in owl_group_config_get() local
432 g = &pctrl->soc->groups[group]; in owl_group_config_get()
434 ret = owl_group_pinconf_reg(g, param, ®, &bit, &width); in owl_group_config_get()
438 arg = owl_read_field(pctrl, reg, bit, width); in owl_group_config_get()
458 u32 reg, bit, width, arg; in owl_group_config_set() local
461 g = &pctrl->soc->groups[group]; in owl_group_config_set()
467 ret = owl_group_pinconf_reg(g, param, ®, &bit, &width); in owl_group_config_set()
476 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_group_config_set()
478 owl_write_field(pctrl, reg, arg, bit, width); in owl_group_config_set()
480 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_group_config_set()
506 for (i = 0; i < pctrl->soc->nports; i++) { in owl_gpio_get_port()
507 const struct owl_gpio_port *port = &pctrl->soc->ports[i]; in owl_gpio_get_port()
509 if (*pin >= start && *pin < start + port->pins) { in owl_gpio_get_port()
510 *pin -= start; in owl_gpio_get_port()
514 start += port->pins; in owl_gpio_get_port()
543 return -ENODEV; in owl_gpio_request()
545 gpio_base = pctrl->base + port->offset; in owl_gpio_request()
551 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_request()
552 owl_gpio_update_reg(gpio_base + port->outen, offset, true); in owl_gpio_request()
553 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_request()
569 gpio_base = pctrl->base + port->offset; in owl_gpio_free()
571 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_free()
572 /* disable gpio output */ in owl_gpio_free()
573 owl_gpio_update_reg(gpio_base + port->outen, offset, false); in owl_gpio_free()
575 /* disable gpio input */ in owl_gpio_free()
576 owl_gpio_update_reg(gpio_base + port->inen, offset, false); in owl_gpio_free()
577 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_free()
590 return -ENODEV; in owl_gpio_get()
592 gpio_base = pctrl->base + port->offset; in owl_gpio_get()
594 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_get()
595 val = readl_relaxed(gpio_base + port->dat); in owl_gpio_get()
596 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_get()
612 gpio_base = pctrl->base + port->offset; in owl_gpio_set()
614 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_set()
615 owl_gpio_update_reg(gpio_base + port->dat, offset, value); in owl_gpio_set()
616 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_set()
628 return -ENODEV; in owl_gpio_direction_input()
630 gpio_base = pctrl->base + port->offset; in owl_gpio_direction_input()
632 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_direction_input()
633 owl_gpio_update_reg(gpio_base + port->outen, offset, false); in owl_gpio_direction_input()
634 owl_gpio_update_reg(gpio_base + port->inen, offset, true); in owl_gpio_direction_input()
635 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_direction_input()
650 return -ENODEV; in owl_gpio_direction_output()
652 gpio_base = pctrl->base + port->offset; in owl_gpio_direction_output()
654 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_direction_output()
655 owl_gpio_update_reg(gpio_base + port->inen, offset, false); in owl_gpio_direction_output()
656 owl_gpio_update_reg(gpio_base + port->outen, offset, true); in owl_gpio_direction_output()
657 owl_gpio_update_reg(gpio_base + port->dat, offset, value); in owl_gpio_direction_output()
658 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_direction_output()
663 static void irq_set_type(struct owl_pinctrl *pctrl, int gpio, unsigned int type) in irq_set_type() argument
678 if (owl_gpio_get(&pctrl->chip, gpio)) in irq_set_type()
704 port = owl_gpio_get_port(pctrl, &gpio); in irq_set_type()
708 gpio_base = pctrl->base + port->offset; in irq_set_type()
710 raw_spin_lock_irqsave(&pctrl->lock, flags); in irq_set_type()
712 offset = (gpio < 16) ? 4 : 0; in irq_set_type()
713 value = readl_relaxed(gpio_base + port->intc_type + offset); in irq_set_type()
714 value &= ~(OWL_GPIO_INT_MASK << ((gpio % 16) * 2)); in irq_set_type()
715 value |= irq_type << ((gpio % 16) * 2); in irq_set_type()
716 writel_relaxed(value, gpio_base + port->intc_type + offset); in irq_set_type()
718 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in irq_set_type()
727 unsigned int gpio = hwirq; in owl_gpio_irq_mask() local
732 port = owl_gpio_get_port(pctrl, &gpio); in owl_gpio_irq_mask()
736 gpio_base = pctrl->base + port->offset; in owl_gpio_irq_mask()
738 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_irq_mask()
740 owl_gpio_update_reg(gpio_base + port->intc_msk, gpio, false); in owl_gpio_irq_mask()
743 val = readl_relaxed(gpio_base + port->intc_msk); in owl_gpio_irq_mask()
745 owl_gpio_update_reg(gpio_base + port->intc_ctl, in owl_gpio_irq_mask()
746 OWL_GPIO_CTLR_ENABLE + port->shared_ctl_offset * 5, false); in owl_gpio_irq_mask()
748 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_irq_mask()
759 unsigned int gpio = hwirq; in owl_gpio_irq_unmask() local
764 port = owl_gpio_get_port(pctrl, &gpio); in owl_gpio_irq_unmask()
770 gpio_base = pctrl->base + port->offset; in owl_gpio_irq_unmask()
771 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_irq_unmask()
774 value = readl_relaxed(gpio_base + port->intc_ctl); in owl_gpio_irq_unmask()
776 << port->shared_ctl_offset * 5); in owl_gpio_irq_unmask()
777 writel_relaxed(value, gpio_base + port->intc_ctl); in owl_gpio_irq_unmask()
779 /* enable GPIO interrupt */ in owl_gpio_irq_unmask()
780 owl_gpio_update_reg(gpio_base + port->intc_msk, gpio, true); in owl_gpio_irq_unmask()
782 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_irq_unmask()
791 unsigned int gpio = hwirq; in owl_gpio_irq_ack() local
806 port = owl_gpio_get_port(pctrl, &gpio); in owl_gpio_irq_ack()
810 gpio_base = pctrl->base + port->offset; in owl_gpio_irq_ack()
812 raw_spin_lock_irqsave(&pctrl->lock, flags); in owl_gpio_irq_ack()
814 owl_gpio_update_reg(gpio_base + port->intc_ctl, in owl_gpio_irq_ack()
815 OWL_GPIO_CTLR_PENDING + port->shared_ctl_offset * 5, true); in owl_gpio_irq_ack()
817 raw_spin_unlock_irqrestore(&pctrl->lock, flags); in owl_gpio_irq_ack()
830 irq_set_type(pctrl, data->hwirq, type); in owl_gpio_irq_set_type()
836 .name = "owl-irq",
849 struct irq_domain *domain = pctrl->chip.irq.domain; in owl_gpio_irq_handler()
858 for (i = 0; i < pctrl->soc->nports; i++) { in owl_gpio_irq_handler()
859 port = &pctrl->soc->ports[i]; in owl_gpio_irq_handler()
860 base = pctrl->base + port->offset; in owl_gpio_irq_handler()
863 if (parent != pctrl->irq[i]) in owl_gpio_irq_handler()
866 pending_irq = readl_relaxed(base + port->intc_pd); in owl_gpio_irq_handler()
868 for_each_set_bit(pin, &pending_irq, port->pins) { in owl_gpio_irq_handler()
872 owl_gpio_update_reg(base + port->intc_pd, pin, true); in owl_gpio_irq_handler()
876 offset += port->pins; in owl_gpio_irq_handler()
888 chip = &pctrl->chip; in owl_gpio_init()
889 chip->base = -1; in owl_gpio_init()
890 chip->ngpio = pctrl->soc->ngpios; in owl_gpio_init()
891 chip->label = dev_name(pctrl->dev); in owl_gpio_init()
892 chip->parent = pctrl->dev; in owl_gpio_init()
893 chip->owner = THIS_MODULE; in owl_gpio_init()
895 gpio_irq = &chip->irq; in owl_gpio_init()
897 gpio_irq->handler = handle_simple_irq; in owl_gpio_init()
898 gpio_irq->default_type = IRQ_TYPE_NONE; in owl_gpio_init()
899 gpio_irq->parent_handler = owl_gpio_irq_handler; in owl_gpio_init()
900 gpio_irq->parent_handler_data = pctrl; in owl_gpio_init()
901 gpio_irq->num_parents = pctrl->num_irq; in owl_gpio_init()
902 gpio_irq->parents = pctrl->irq; in owl_gpio_init()
904 gpio_irq->map = devm_kcalloc(pctrl->dev, chip->ngpio, in owl_gpio_init()
905 sizeof(*gpio_irq->map), GFP_KERNEL); in owl_gpio_init()
906 if (!gpio_irq->map) in owl_gpio_init()
907 return -ENOMEM; in owl_gpio_init()
909 for (i = 0, offset = 0; i < pctrl->soc->nports; i++) { in owl_gpio_init()
910 const struct owl_gpio_port *port = &pctrl->soc->ports[i]; in owl_gpio_init()
912 for (j = 0; j < port->pins; j++) in owl_gpio_init()
913 gpio_irq->map[offset + j] = gpio_irq->parents[i]; in owl_gpio_init()
915 offset += port->pins; in owl_gpio_init()
918 ret = gpiochip_add_data(&pctrl->chip, pctrl); in owl_gpio_init()
920 dev_err(pctrl->dev, "failed to register gpiochip\n"); in owl_gpio_init()
933 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); in owl_pinctrl_probe()
935 return -ENOMEM; in owl_pinctrl_probe()
937 pctrl->base = devm_platform_ioremap_resource(pdev, 0); in owl_pinctrl_probe()
938 if (IS_ERR(pctrl->base)) in owl_pinctrl_probe()
939 return PTR_ERR(pctrl->base); in owl_pinctrl_probe()
941 /* enable GPIO/MFP clock */ in owl_pinctrl_probe()
942 pctrl->clk = devm_clk_get(&pdev->dev, NULL); in owl_pinctrl_probe()
943 if (IS_ERR(pctrl->clk)) { in owl_pinctrl_probe()
944 dev_err(&pdev->dev, "no clock defined\n"); in owl_pinctrl_probe()
945 return PTR_ERR(pctrl->clk); in owl_pinctrl_probe()
948 ret = clk_prepare_enable(pctrl->clk); in owl_pinctrl_probe()
950 dev_err(&pdev->dev, "clk enable failed\n"); in owl_pinctrl_probe()
954 raw_spin_lock_init(&pctrl->lock); in owl_pinctrl_probe()
956 owl_pinctrl_desc.name = dev_name(&pdev->dev); in owl_pinctrl_probe()
957 owl_pinctrl_desc.pins = soc_data->pins; in owl_pinctrl_probe()
958 owl_pinctrl_desc.npins = soc_data->npins; in owl_pinctrl_probe()
960 pctrl->chip.direction_input = owl_gpio_direction_input; in owl_pinctrl_probe()
961 pctrl->chip.direction_output = owl_gpio_direction_output; in owl_pinctrl_probe()
962 pctrl->chip.get = owl_gpio_get; in owl_pinctrl_probe()
963 pctrl->chip.set = owl_gpio_set; in owl_pinctrl_probe()
964 pctrl->chip.request = owl_gpio_request; in owl_pinctrl_probe()
965 pctrl->chip.free = owl_gpio_free; in owl_pinctrl_probe()
967 pctrl->soc = soc_data; in owl_pinctrl_probe()
968 pctrl->dev = &pdev->dev; in owl_pinctrl_probe()
970 pctrl->pctrldev = devm_pinctrl_register(&pdev->dev, in owl_pinctrl_probe()
972 if (IS_ERR(pctrl->pctrldev)) { in owl_pinctrl_probe()
973 dev_err(&pdev->dev, "could not register Actions OWL pinmux driver\n"); in owl_pinctrl_probe()
974 ret = PTR_ERR(pctrl->pctrldev); in owl_pinctrl_probe()
982 pctrl->num_irq = ret; in owl_pinctrl_probe()
984 pctrl->irq = devm_kcalloc(&pdev->dev, pctrl->num_irq, in owl_pinctrl_probe()
985 sizeof(*pctrl->irq), GFP_KERNEL); in owl_pinctrl_probe()
986 if (!pctrl->irq) { in owl_pinctrl_probe()
987 ret = -ENOMEM; in owl_pinctrl_probe()
991 for (i = 0; i < pctrl->num_irq ; i++) { in owl_pinctrl_probe()
995 pctrl->irq[i] = ret; in owl_pinctrl_probe()
1007 clk_disable_unprepare(pctrl->clk); in owl_pinctrl_probe()