Lines Matching +full:gpio +full:- +full:cfg

1 // SPDX-License-Identifier: GPL-2.0-only
4 * depends on gpio-nomadik and some handling is intertwined; see nmk_gpio_chips
5 * which is used by this driver to access the GPIO banks array.
10 * Copyright (C) 2011-2013 Linus Walleij <linus.walleij@linaro.org>
18 #include <linux/gpio/driver.h>
41 #include "../pinctrl-utils.h"
43 #include <linux/gpio/gpio-nomadik.h>
46 * pin configurations are represented by 32-bit integers:
48 * bit 0.. 8 - Pin Number (512 Pins Maximum)
49 * bit 9..10 - Alternate Function Selection
50 * bit 11..12 - Pull up/down state
51 * bit 13 - Sleep mode behaviour
52 * bit 14 - Direction
53 * bit 15 - Value (if output)
54 * bit 16..18 - SLPM pull up/down state
55 * bit 19..20 - SLPM direction
56 * bit 21..22 - SLPM Value (if output)
57 * bit 23..25 - PDIS value (if input)
58 * bit 26 - Gpio mode
59 * bit 27 - Sleep mode
63 * PIN_CFG_DEFAULT - default config (0):
72 * PIN_CFG - default config with alternate function
103 #define PIN_SLPM_GPIO PIN_SLPM_WAKEUP_ENABLE /* In SLPM, pin is a gpio */
197 * struct nmk_pinctrl - state container for the Nomadik pin controller
220 afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~BIT(offset); in __nmk_gpio_set_mode()
221 bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~BIT(offset); in __nmk_gpio_set_mode()
226 writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA); in __nmk_gpio_set_mode()
227 writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB); in __nmk_gpio_set_mode()
235 pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS); in __nmk_gpio_set_pull()
238 nmk_chip->pull_up &= ~BIT(offset); in __nmk_gpio_set_pull()
243 writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS); in __nmk_gpio_set_pull()
246 nmk_chip->pull_up |= BIT(offset); in __nmk_gpio_set_pull()
247 writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATS); in __nmk_gpio_set_pull()
249 nmk_chip->pull_up &= ~BIT(offset); in __nmk_gpio_set_pull()
250 writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DATC); in __nmk_gpio_set_pull()
257 bool enabled = nmk_chip->lowemi & BIT(offset); in __nmk_gpio_set_lowemi()
263 nmk_chip->lowemi |= BIT(offset); in __nmk_gpio_set_lowemi()
265 nmk_chip->lowemi &= ~BIT(offset); in __nmk_gpio_set_lowemi()
267 writel_relaxed(nmk_chip->lowemi, in __nmk_gpio_set_lowemi()
268 nmk_chip->addr + NMK_GPIO_LOWEMI); in __nmk_gpio_set_lowemi()
274 writel(BIT(offset), nmk_chip->addr + NMK_GPIO_DIRC); in __nmk_gpio_make_input()
281 u32 rwimsc = nmk_chip->rwimsc; in __nmk_gpio_set_mode_safe()
282 u32 fwimsc = nmk_chip->fwimsc; in __nmk_gpio_set_mode_safe()
284 if (glitch && nmk_chip->set_ioforce) { in __nmk_gpio_set_mode_safe()
288 writel(rwimsc & ~bit, nmk_chip->addr + NMK_GPIO_RWIMSC); in __nmk_gpio_set_mode_safe()
289 writel(fwimsc & ~bit, nmk_chip->addr + NMK_GPIO_FWIMSC); in __nmk_gpio_set_mode_safe()
291 nmk_chip->set_ioforce(true); in __nmk_gpio_set_mode_safe()
296 if (glitch && nmk_chip->set_ioforce) { in __nmk_gpio_set_mode_safe()
297 nmk_chip->set_ioforce(false); in __nmk_gpio_set_mode_safe()
299 writel(rwimsc, nmk_chip->addr + NMK_GPIO_RWIMSC); in __nmk_gpio_set_mode_safe()
300 writel(fwimsc, nmk_chip->addr + NMK_GPIO_FWIMSC); in __nmk_gpio_set_mode_safe()
307 u32 falling = nmk_chip->fimsc & BIT(offset); in nmk_gpio_disable_lazy_irq()
308 u32 rising = nmk_chip->rimsc & BIT(offset); in nmk_gpio_disable_lazy_irq()
309 int gpio = nmk_chip->chip.base + offset; in nmk_gpio_disable_lazy_irq() local
310 int irq = irq_find_mapping(nmk_chip->chip.irq.domain, offset); in nmk_gpio_disable_lazy_irq()
320 nmk_chip->rimsc &= ~BIT(offset); in nmk_gpio_disable_lazy_irq()
321 writel_relaxed(nmk_chip->rimsc, in nmk_gpio_disable_lazy_irq()
322 nmk_chip->addr + NMK_GPIO_RIMSC); in nmk_gpio_disable_lazy_irq()
326 nmk_chip->fimsc &= ~BIT(offset); in nmk_gpio_disable_lazy_irq()
327 writel_relaxed(nmk_chip->fimsc, in nmk_gpio_disable_lazy_irq()
328 nmk_chip->addr + NMK_GPIO_FIMSC); in nmk_gpio_disable_lazy_irq()
331 dev_dbg(nmk_chip->chip.parent, "%d: clearing interrupt mask\n", gpio); in nmk_gpio_disable_lazy_irq()
353 if (!npct->prcm_base) in nmk_prcm_altcx_set_mode()
357 dev_err(npct->dev, "PRCM GPIOCR: alternate-C%i is invalid\n", in nmk_prcm_altcx_set_mode()
362 for (i = 0 ; i < npct->soc->npins_altcx ; i++) { in nmk_prcm_altcx_set_mode()
363 if (npct->soc->altcx_pins[i].pin == offset) in nmk_prcm_altcx_set_mode()
366 if (i == npct->soc->npins_altcx) { in nmk_prcm_altcx_set_mode()
367 dev_dbg(npct->dev, "PRCM GPIOCR: pin %i is not found\n", in nmk_prcm_altcx_set_mode()
372 pin_desc = npct->soc->altcx_pins + i; in nmk_prcm_altcx_set_mode()
373 gpiocr_regs = npct->soc->prcm_gpiocr_registers; in nmk_prcm_altcx_set_mode()
381 if (pin_desc->altcx[i].used) { in nmk_prcm_altcx_set_mode()
382 reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; in nmk_prcm_altcx_set_mode()
383 bit = pin_desc->altcx[i].control_bit; in nmk_prcm_altcx_set_mode()
384 if (readl(npct->prcm_base + reg) & BIT(bit)) { in nmk_prcm_altcx_set_mode()
385 nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); in nmk_prcm_altcx_set_mode()
386 dev_dbg(npct->dev, in nmk_prcm_altcx_set_mode()
387 "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", in nmk_prcm_altcx_set_mode()
395 alt_index = alt_num - 1; in nmk_prcm_altcx_set_mode()
396 if (!pin_desc->altcx[alt_index].used) { in nmk_prcm_altcx_set_mode()
397 dev_warn(npct->dev, in nmk_prcm_altcx_set_mode()
398 "PRCM GPIOCR: pin %i: alternate-C%i does not exist\n", in nmk_prcm_altcx_set_mode()
410 if (pin_desc->altcx[i].used) { in nmk_prcm_altcx_set_mode()
411 reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; in nmk_prcm_altcx_set_mode()
412 bit = pin_desc->altcx[i].control_bit; in nmk_prcm_altcx_set_mode()
413 if (readl(npct->prcm_base + reg) & BIT(bit)) { in nmk_prcm_altcx_set_mode()
414 nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); in nmk_prcm_altcx_set_mode()
415 dev_dbg(npct->dev, in nmk_prcm_altcx_set_mode()
416 "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", in nmk_prcm_altcx_set_mode()
422 reg = gpiocr_regs[pin_desc->altcx[alt_index].reg_index]; in nmk_prcm_altcx_set_mode()
423 bit = pin_desc->altcx[alt_index].control_bit; in nmk_prcm_altcx_set_mode()
424 dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n", in nmk_prcm_altcx_set_mode()
426 nmk_write_masked(npct->prcm_base + reg, BIT(bit), BIT(bit)); in nmk_prcm_altcx_set_mode()
430 * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
431 * - Save SLPM registers
432 * - Set SLPM=0 for the IOs you want to switch and others to 1
433 * - Configure the GPIO registers for the IOs that are being switched
434 * - Set IOFORCE=1
435 * - Modify the AFLSA/B registers for the IOs that are being switched
436 * - Set IOFORCE=0
437 * - Restore SLPM registers
438 * - Any spurious wake up event during switch sequence to be ignored and
452 clk_enable(chip->clk); in nmk_gpio_glitch_slpm_init()
454 slpm[i] = readl(chip->addr + NMK_GPIO_SLPC); in nmk_gpio_glitch_slpm_init()
455 writel(temp, chip->addr + NMK_GPIO_SLPC); in nmk_gpio_glitch_slpm_init()
469 writel(slpm[i], chip->addr + NMK_GPIO_SLPC); in nmk_gpio_glitch_slpm_restore()
471 clk_disable(chip->clk); in nmk_gpio_glitch_slpm_restore()
475 /* Only called by gpio-nomadik but requires knowledge of struct nmk_pinctrl. */
476 int __maybe_unused nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio) in nmk_prcm_gpiocr_get_mode() argument
485 if (!npct->prcm_base) in nmk_prcm_gpiocr_get_mode()
488 for (i = 0; i < npct->soc->npins_altcx; i++) { in nmk_prcm_gpiocr_get_mode()
489 if (npct->soc->altcx_pins[i].pin == gpio) in nmk_prcm_gpiocr_get_mode()
492 if (i == npct->soc->npins_altcx) in nmk_prcm_gpiocr_get_mode()
495 pin_desc = npct->soc->altcx_pins + i; in nmk_prcm_gpiocr_get_mode()
496 gpiocr_regs = npct->soc->prcm_gpiocr_registers; in nmk_prcm_gpiocr_get_mode()
498 if (pin_desc->altcx[i].used) { in nmk_prcm_gpiocr_get_mode()
499 reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; in nmk_prcm_gpiocr_get_mode()
500 bit = pin_desc->altcx[i].control_bit; in nmk_prcm_gpiocr_get_mode()
501 if (readl(npct->prcm_base + reg) & BIT(bit)) in nmk_prcm_gpiocr_get_mode()
512 return npct->soc->ngroups; in nmk_get_groups_cnt()
520 return npct->soc->groups[selector].grp.name; in nmk_get_group_name()
529 *pins = npct->soc->groups[selector].grp.pins; in nmk_get_group_pins()
530 *num_pins = npct->soc->groups[selector].grp.npins; in nmk_get_group_pins()
534 /* This makes the mapping from pin number to a GPIO chip. We also return the pin
535 * offset in the GPIO chip for convenience (and to avoid a second loop).
548 if (pin >= j && pin < j + nmk_gpio->chip.ngpio) { in find_nmk_gpio_from_pin()
550 *offset = pin - j; in find_nmk_gpio_from_pin()
553 j += nmk_gpio->chip.ngpio; in find_nmk_gpio_from_pin()
563 return &nmk_gpio->chip; in find_gc_from_pin()
576 nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset); in nmk_pin_dbg_show()
584 return -ENOSPC; in nmk_dt_add_map_mux()
602 return -ENOSPC; in nmk_dt_add_map_configs()
606 return -ENOMEM; in nmk_dt_add_map_configs()
678 NMK_CONFIG_PIN_ARRAY("ste,sleep-input", nmk_pin_sleep_input_modes),
679 NMK_CONFIG_PIN_ARRAY("ste,sleep-output", nmk_pin_sleep_output_modes),
680 NMK_CONFIG_PIN_ARRAY("ste,sleep-wakeup", nmk_pin_sleep_wakeup_modes),
681 NMK_CONFIG_PIN_ARRAY("ste,gpio", nmk_pin_gpio_modes),
682 NMK_CONFIG_PIN_ARRAY("ste,sleep-pull-disable", nmk_pin_sleep_pdis_modes),
704 if (sscanf((char *)pin_name, "GPIO%d", &pin_number) == 1) in nmk_find_pin_name()
705 for (i = 0; i < npct->soc->npins; i++) in nmk_find_pin_name()
706 if (npct->soc->pins[i].number == pin_number) in nmk_find_pin_name()
707 return npct->soc->pins[i].name; in nmk_find_pin_name()
715 unsigned long cfg = 0; in nmk_pinctrl_dt_get_config() local
720 if (ret != -EINVAL) { in nmk_pinctrl_dt_get_config()
721 if (nmk_dt_pin_config(i, val, &cfg) == 0) { in nmk_pinctrl_dt_get_config()
722 *configs |= cfg; in nmk_pinctrl_dt_get_config()
837 return npct->soc->nfunctions; in nmk_pmx_get_funcs_cnt()
845 return npct->soc->functions[function].name; in nmk_pmx_get_func_name()
855 *groups = npct->soc->functions[function].groups; in nmk_pmx_get_func_groups()
856 *num_groups = npct->soc->functions[function].ngroups; in nmk_pmx_get_func_groups()
869 int ret = -EINVAL; in nmk_pmx_set()
872 g = &npct->soc->groups[group]; in nmk_pmx_set()
874 if (g->altsetting < 0) in nmk_pmx_set()
875 return -EINVAL; in nmk_pmx_set()
877 dev_dbg(npct->dev, "enable group %s, %zu pins\n", g->grp.name, g->grp.npins); in nmk_pmx_set()
884 * Safe sequence used to switch IOs between GPIO and Alternate-C mode: in nmk_pmx_set()
885 * - Save SLPM registers (since we have a shadow register in the in nmk_pmx_set()
887 * - Set SLPM=0 for the IOs you want to switch and others to 1 in nmk_pmx_set()
888 * - Configure the GPIO registers for the IOs that are being switched in nmk_pmx_set()
889 * - Set IOFORCE=1 in nmk_pmx_set()
890 * - Modify the AFLSA/B registers for the IOs that are being switched in nmk_pmx_set()
891 * - Set IOFORCE=0 in nmk_pmx_set()
892 * - Restore SLPM registers in nmk_pmx_set()
893 * - Any spurious wake up event during switch sequence to be ignored in nmk_pmx_set()
900 glitch = ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C); in nmk_pmx_set()
912 for (i = 0; i < g->grp.npins; i++) { in nmk_pmx_set()
916 nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], &bit); in nmk_pmx_set()
918 dev_err(npct->dev, in nmk_pmx_set()
920 g->grp.pins[i], g->grp.name, i); in nmk_pmx_set()
924 slpm[nmk_chip->bank] &= ~BIT(bit); in nmk_pmx_set()
929 for (i = 0; i < g->grp.npins; i++) { in nmk_pmx_set()
933 nmk_chip = find_nmk_gpio_from_pin(g->grp.pins[i], &bit); in nmk_pmx_set()
935 dev_err(npct->dev, in nmk_pmx_set()
937 g->grp.pins[i], g->grp.name, i); in nmk_pmx_set()
940 dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", in nmk_pmx_set()
941 g->grp.pins[i], g->altsetting); in nmk_pmx_set()
943 clk_enable(nmk_chip->clk); in nmk_pmx_set()
954 (g->altsetting & NMK_GPIO_ALT_C), glitch); in nmk_pmx_set()
955 clk_disable(nmk_chip->clk); in nmk_pmx_set()
960 * - If selection is a ALTCx, some bits in PRCM GPIOCR registers in nmk_pmx_set()
962 * - If selection is pure ALTC and previous selection was ALTCx, in nmk_pmx_set()
965 if ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C) in nmk_pmx_set()
966 nmk_prcm_altcx_set_mode(npct, g->grp.pins[i], in nmk_pmx_set()
967 g->altsetting >> NMK_GPIO_ALT_CX_SHIFT); in nmk_pmx_set()
993 dev_err(npct->dev, "invalid range\n"); in nmk_gpio_request_enable()
994 return -EINVAL; in nmk_gpio_request_enable()
996 if (!range->gc) { in nmk_gpio_request_enable()
997 dev_err(npct->dev, "missing GPIO chip in range\n"); in nmk_gpio_request_enable()
998 return -EINVAL; in nmk_gpio_request_enable()
1000 chip = range->gc; in nmk_gpio_request_enable()
1003 dev_dbg(npct->dev, "enable pin %u as GPIO\n", pin); in nmk_gpio_request_enable()
1007 clk_enable(nmk_chip->clk); in nmk_gpio_request_enable()
1008 /* There is no glitch when converting any pin to GPIO */ in nmk_gpio_request_enable()
1010 clk_disable(nmk_chip->clk); in nmk_gpio_request_enable()
1021 dev_dbg(npct->dev, "disable pin %u as GPIO\n", pin); in nmk_gpio_disable_free()
1022 /* Set the pin to some default state, GPIO is usually default */ in nmk_gpio_disable_free()
1039 return -EINVAL; in nmk_pin_config_get()
1053 [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup", in nmk_pin_config_set()
1058 unsigned long cfg; in nmk_pin_config_set() local
1064 dev_err(npct->dev, in nmk_pin_config_set()
1066 return -EINVAL; in nmk_pin_config_set()
1075 cfg = configs[i]; in nmk_pin_config_set()
1076 pull = PIN_PULL(cfg); in nmk_pin_config_set()
1077 slpm = PIN_SLPM(cfg); in nmk_pin_config_set()
1078 output = PIN_DIR(cfg); in nmk_pin_config_set()
1079 val = PIN_VAL(cfg); in nmk_pin_config_set()
1080 lowemi = PIN_LOWEMI(cfg); in nmk_pin_config_set()
1081 gpiomode = PIN_GPIOMODE(cfg); in nmk_pin_config_set()
1082 sleep = PIN_SLEEPMODE(cfg); in nmk_pin_config_set()
1085 int slpm_pull = PIN_SLPM_PULL(cfg); in nmk_pin_config_set()
1086 int slpm_output = PIN_SLPM_DIR(cfg); in nmk_pin_config_set()
1087 int slpm_val = PIN_SLPM_VAL(cfg); in nmk_pin_config_set()
1089 /* All pins go into GPIO mode at sleep */ in nmk_pin_config_set()
1097 pull = slpm_pull - 1; in nmk_pin_config_set()
1099 output = slpm_output - 1; in nmk_pin_config_set()
1101 val = slpm_val - 1; in nmk_pin_config_set()
1103 dev_dbg(nmk_chip->chip.parent, in nmk_pin_config_set()
1112 dev_dbg(nmk_chip->chip.parent, in nmk_pin_config_set()
1114 pin, cfg, pullnames[pull], slpmnames[slpm], in nmk_pin_config_set()
1119 clk_enable(nmk_chip->clk); in nmk_pin_config_set()
1121 /* No glitch when going to GPIO mode */ in nmk_pin_config_set()
1133 clk_disable(nmk_chip->clk); in nmk_pin_config_set()
1145 .name = "pinctrl-nomadik",
1154 .compatible = "stericsson,stn8815-pinctrl",
1158 .compatible = "stericsson,db8500-pinctrl",
1171 return -EINVAL; in nmk_pinctrl_suspend()
1173 return pinctrl_force_sleep(npct->pctl); in nmk_pinctrl_suspend()
1182 return -EINVAL; in nmk_pinctrl_resume()
1184 return pinctrl_force_default(npct->pctl); in nmk_pinctrl_resume()
1190 struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev); in nmk_pinctrl_probe()
1196 npct = devm_kzalloc(&pdev->dev, sizeof(*npct), GFP_KERNEL); in nmk_pinctrl_probe()
1198 return -ENOMEM; in nmk_pinctrl_probe()
1200 version = (uintptr_t)device_get_match_data(&pdev->dev); in nmk_pinctrl_probe()
1204 nmk_pinctrl_stn8815_init(&npct->soc); in nmk_pinctrl_probe()
1206 nmk_pinctrl_db8500_init(&npct->soc); in nmk_pinctrl_probe()
1209 * Since we depend on the GPIO chips to provide clock and register base in nmk_pinctrl_probe()
1212 * them. The GPIO portion of the actual hardware may be probed before in nmk_pinctrl_probe()
1219 gpio_fwnode = fwnode_find_reference(fwnode, "nomadik-gpio-chips", i); in nmk_pinctrl_probe()
1223 dev_info(&pdev->dev, "populate NMK GPIO %d \"%pfwP\"\n", i, gpio_fwnode); in nmk_pinctrl_probe()
1226 dev_err(&pdev->dev, in nmk_pinctrl_probe()
1227 "could not populate nmk chip struct - continue anyway\n"); in nmk_pinctrl_probe()
1229 /* We are NOT compatible with mobileye,eyeq5-gpio. */ in nmk_pinctrl_probe()
1230 BUG_ON(nmk_chip->is_mobileye_soc); in nmk_pinctrl_probe()
1236 npct->prcm_base = fwnode_iomap(prcm_fwnode, 0); in nmk_pinctrl_probe()
1239 if (!npct->prcm_base) { in nmk_pinctrl_probe()
1241 dev_info(&pdev->dev, in nmk_pinctrl_probe()
1242 "No PRCM base, assuming no ALT-Cx control is available\n"); in nmk_pinctrl_probe()
1244 dev_err(&pdev->dev, "missing PRCM base address\n"); in nmk_pinctrl_probe()
1245 return -EINVAL; in nmk_pinctrl_probe()
1249 nmk_pinctrl_desc.pins = npct->soc->pins; in nmk_pinctrl_probe()
1250 nmk_pinctrl_desc.npins = npct->soc->npins; in nmk_pinctrl_probe()
1251 npct->dev = &pdev->dev; in nmk_pinctrl_probe()
1253 npct->pctl = devm_pinctrl_register(&pdev->dev, &nmk_pinctrl_desc, npct); in nmk_pinctrl_probe()
1254 if (IS_ERR(npct->pctl)) { in nmk_pinctrl_probe()
1255 dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n"); in nmk_pinctrl_probe()
1256 return PTR_ERR(npct->pctl); in nmk_pinctrl_probe()
1260 dev_info(&pdev->dev, "initialized Nomadik pin control driver\n"); in nmk_pinctrl_probe()
1271 .name = "pinctrl-nomadik",