Lines Matching +full:bias +full:- +full:pull +full:- +full:pin +full:- +full:default
1 // SPDX-License-Identifier: GPL-2.0-only
17 #include <linux/pinctrl/pinconf-generic.h>
22 #include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
25 #include "../pinctrl-utils.h"
36 /* bias */
59 * struct pm8xxx_pin_data - dynamic configuration for a pin
63 * @mode: operating mode for the pin (input/output)
64 * @open_drain: output buffer configured as open-drain (vs push-pull)
66 * @bias: register view of configured bias
67 * @pull_up_strength: placeholder for selected pull up strength
68 * only used to configure bias when pull up is selected
69 * @output_strength: selector of output-strength
70 * @disable: pin disabled / configured as tristate
72 * @inverted: pin logic is inverted
80 u8 bias; member
99 {"qcom,drive-strength", PM8XXX_QCOM_DRIVE_STRENGH, 0},
100 {"qcom,pull-up-strength", PM8XXX_QCOM_PULL_UP_STRENGTH, 0},
105 PCONFDUMP(PM8XXX_QCOM_DRIVE_STRENGH, "drive-strength", NULL, true),
106 PCONFDUMP(PM8XXX_QCOM_PULL_UP_STRENGTH, "pull up strength", NULL, true),
128 struct pm8xxx_pin_data *pin, int bank) in pm8xxx_read_bank() argument
133 ret = regmap_write(pctrl->regmap, pin->reg, val); in pm8xxx_read_bank()
135 dev_err(pctrl->dev, "failed to select bank %d\n", bank); in pm8xxx_read_bank()
139 ret = regmap_read(pctrl->regmap, pin->reg, &val); in pm8xxx_read_bank()
141 dev_err(pctrl->dev, "failed to read register %d\n", bank); in pm8xxx_read_bank()
149 struct pm8xxx_pin_data *pin, in pm8xxx_write_bank() argument
158 ret = regmap_write(pctrl->regmap, pin->reg, val); in pm8xxx_write_bank()
160 dev_err(pctrl->dev, "failed to write register\n"); in pm8xxx_write_bank()
169 return pctrl->npins; in pm8xxx_get_groups_count()
186 *pins = &pctrl->desc.pins[group].number; in pm8xxx_get_group_pins()
219 *num_groups = pctrl->npins; in pm8xxx_get_function_groups()
228 struct pm8xxx_pin_data *pin = pctrl->desc.pins[group].drv_data; in pm8xxx_pinmux_set_mux() local
231 pin->function = function; in pm8xxx_pinmux_set_mux()
232 val = pin->function << 1; in pm8xxx_pinmux_set_mux()
234 pm8xxx_write_bank(pctrl, pin, 4, val); in pm8xxx_pinmux_set_mux()
251 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data; in pm8xxx_pin_config_get() local
257 if (pin->bias != PM8XXX_GPIO_BIAS_NP) in pm8xxx_pin_config_get()
258 return -EINVAL; in pm8xxx_pin_config_get()
262 if (pin->bias != PM8XXX_GPIO_BIAS_PD) in pm8xxx_pin_config_get()
263 return -EINVAL; in pm8xxx_pin_config_get()
267 if (pin->bias > PM8XXX_GPIO_BIAS_PU_1P5_30) in pm8xxx_pin_config_get()
268 return -EINVAL; in pm8xxx_pin_config_get()
272 arg = pin->pull_up_strength; in pm8xxx_pin_config_get()
275 if (!pin->disable) in pm8xxx_pin_config_get()
276 return -EINVAL; in pm8xxx_pin_config_get()
280 if (pin->mode != PM8XXX_GPIO_MODE_INPUT) in pm8xxx_pin_config_get()
281 return -EINVAL; in pm8xxx_pin_config_get()
285 if (pin->mode & PM8XXX_GPIO_MODE_OUTPUT) in pm8xxx_pin_config_get()
286 arg = pin->output_value; in pm8xxx_pin_config_get()
291 arg = pin->power_source; in pm8xxx_pin_config_get()
294 arg = pin->output_strength; in pm8xxx_pin_config_get()
297 if (pin->open_drain) in pm8xxx_pin_config_get()
298 return -EINVAL; in pm8xxx_pin_config_get()
302 if (!pin->open_drain) in pm8xxx_pin_config_get()
303 return -EINVAL; in pm8xxx_pin_config_get()
306 default: in pm8xxx_pin_config_get()
307 return -EINVAL; in pm8xxx_pin_config_get()
321 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data; in pm8xxx_pin_config_set() local
334 pin->bias = PM8XXX_GPIO_BIAS_NP; in pm8xxx_pin_config_set()
336 pin->disable = 0; in pm8xxx_pin_config_set()
340 pin->bias = PM8XXX_GPIO_BIAS_PD; in pm8xxx_pin_config_set()
342 pin->disable = 0; in pm8xxx_pin_config_set()
347 dev_err(pctrl->dev, "invalid pull-up strength\n"); in pm8xxx_pin_config_set()
348 return -EINVAL; in pm8xxx_pin_config_set()
350 pin->pull_up_strength = arg; in pm8xxx_pin_config_set()
353 pin->bias = pin->pull_up_strength; in pm8xxx_pin_config_set()
355 pin->disable = 0; in pm8xxx_pin_config_set()
359 pin->disable = 1; in pm8xxx_pin_config_set()
363 pin->mode = PM8XXX_GPIO_MODE_INPUT; in pm8xxx_pin_config_set()
367 pin->mode = PM8XXX_GPIO_MODE_OUTPUT; in pm8xxx_pin_config_set()
368 pin->output_value = !!arg; in pm8xxx_pin_config_set()
372 pin->power_source = arg; in pm8xxx_pin_config_set()
377 dev_err(pctrl->dev, "invalid drive strength\n"); in pm8xxx_pin_config_set()
378 return -EINVAL; in pm8xxx_pin_config_set()
380 pin->output_strength = arg; in pm8xxx_pin_config_set()
384 pin->open_drain = 0; in pm8xxx_pin_config_set()
388 pin->open_drain = 1; in pm8xxx_pin_config_set()
391 default: in pm8xxx_pin_config_set()
392 dev_err(pctrl->dev, in pm8xxx_pin_config_set()
395 return -EINVAL; in pm8xxx_pin_config_set()
400 val = pin->power_source << 1; in pm8xxx_pin_config_set()
402 pm8xxx_write_bank(pctrl, pin, 0, val); in pm8xxx_pin_config_set()
406 val = pin->mode << 2; in pm8xxx_pin_config_set()
407 val |= pin->open_drain << 1; in pm8xxx_pin_config_set()
408 val |= pin->output_value; in pm8xxx_pin_config_set()
409 pm8xxx_write_bank(pctrl, pin, 1, val); in pm8xxx_pin_config_set()
413 val = pin->bias << 1; in pm8xxx_pin_config_set()
414 pm8xxx_write_bank(pctrl, pin, 2, val); in pm8xxx_pin_config_set()
418 val = pin->output_strength << 2; in pm8xxx_pin_config_set()
419 val |= pin->disable; in pm8xxx_pin_config_set()
420 pm8xxx_write_bank(pctrl, pin, 3, val); in pm8xxx_pin_config_set()
424 val = pin->function << 1; in pm8xxx_pin_config_set()
425 pm8xxx_write_bank(pctrl, pin, 4, val); in pm8xxx_pin_config_set()
430 if (!pin->inverted) in pm8xxx_pin_config_set()
432 pm8xxx_write_bank(pctrl, pin, 5, val); in pm8xxx_pin_config_set()
456 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data; in pm8xxx_gpio_direction_input() local
459 pin->mode = PM8XXX_GPIO_MODE_INPUT; in pm8xxx_gpio_direction_input()
460 val = pin->mode << 2; in pm8xxx_gpio_direction_input()
462 pm8xxx_write_bank(pctrl, pin, 1, val); in pm8xxx_gpio_direction_input()
472 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data; in pm8xxx_gpio_direction_output() local
475 pin->mode = PM8XXX_GPIO_MODE_OUTPUT; in pm8xxx_gpio_direction_output()
476 pin->output_value = !!value; in pm8xxx_gpio_direction_output()
478 val = pin->mode << 2; in pm8xxx_gpio_direction_output()
479 val |= pin->open_drain << 1; in pm8xxx_gpio_direction_output()
480 val |= pin->output_value; in pm8xxx_gpio_direction_output()
482 pm8xxx_write_bank(pctrl, pin, 1, val); in pm8xxx_gpio_direction_output()
490 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data; in pm8xxx_gpio_get() local
494 if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT) in pm8xxx_gpio_get()
495 return pin->output_value; in pm8xxx_gpio_get()
497 irq = chip->to_irq(chip, offset); in pm8xxx_gpio_get()
504 ret = -EINVAL; in pm8xxx_gpio_get()
512 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data; in pm8xxx_gpio_set() local
515 pin->output_value = !!value; in pm8xxx_gpio_set()
517 val = pin->mode << 2; in pm8xxx_gpio_set()
518 val |= pin->open_drain << 1; in pm8xxx_gpio_set()
519 val |= pin->output_value; in pm8xxx_gpio_set()
521 pm8xxx_write_bank(pctrl, pin, 1, val); in pm8xxx_gpio_set()
528 if (chip->of_gpio_n_cells < 2) in pm8xxx_gpio_of_xlate()
529 return -EINVAL; in pm8xxx_gpio_of_xlate()
532 *flags = gpio_desc->args[1]; in pm8xxx_gpio_of_xlate()
534 return gpio_desc->args[0] - PM8XXX_GPIO_PHYSICAL_OFFSET; in pm8xxx_gpio_of_xlate()
547 struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data; in pm8xxx_gpio_dbg_show_one() local
553 "pull-up 30uA", "pull-up 1.5uA", "pull-up 31.5uA", in pm8xxx_gpio_dbg_show_one()
554 "pull-up 1.5uA + 30uA boost", "pull-down 10uA", "no pull" in pm8xxx_gpio_dbg_show_one()
557 "push-pull", "open-drain" in pm8xxx_gpio_dbg_show_one()
563 seq_printf(s, " gpio%-2d:", offset + PM8XXX_GPIO_PHYSICAL_OFFSET); in pm8xxx_gpio_dbg_show_one()
564 if (pin->disable) { in pm8xxx_gpio_dbg_show_one()
565 seq_puts(s, " ---"); in pm8xxx_gpio_dbg_show_one()
567 seq_printf(s, " %-4s", modes[pin->mode]); in pm8xxx_gpio_dbg_show_one()
568 seq_printf(s, " %-7s", pm8xxx_gpio_functions[pin->function]); in pm8xxx_gpio_dbg_show_one()
569 seq_printf(s, " VIN%d", pin->power_source); in pm8xxx_gpio_dbg_show_one()
570 seq_printf(s, " %-27s", biases[pin->bias]); in pm8xxx_gpio_dbg_show_one()
571 seq_printf(s, " %-10s", buffer_types[pin->open_drain]); in pm8xxx_gpio_dbg_show_one()
572 seq_printf(s, " %-4s", pin->output_value ? "high" : "low"); in pm8xxx_gpio_dbg_show_one()
573 seq_printf(s, " %-7s", strengths[pin->output_strength]); in pm8xxx_gpio_dbg_show_one()
574 if (pin->inverted) in pm8xxx_gpio_dbg_show_one()
581 unsigned gpio = chip->base; in pm8xxx_gpio_dbg_show()
584 for (i = 0; i < chip->ngpio; i++, gpio++) { in pm8xxx_gpio_dbg_show()
605 struct pm8xxx_pin_data *pin) in pm8xxx_pin_populate() argument
609 val = pm8xxx_read_bank(pctrl, pin, 0); in pm8xxx_pin_populate()
613 pin->power_source = (val >> 1) & 0x7; in pm8xxx_pin_populate()
615 val = pm8xxx_read_bank(pctrl, pin, 1); in pm8xxx_pin_populate()
619 pin->mode = (val >> 2) & 0x3; in pm8xxx_pin_populate()
620 pin->open_drain = !!(val & BIT(1)); in pm8xxx_pin_populate()
621 pin->output_value = val & BIT(0); in pm8xxx_pin_populate()
623 val = pm8xxx_read_bank(pctrl, pin, 2); in pm8xxx_pin_populate()
627 pin->bias = (val >> 1) & 0x7; in pm8xxx_pin_populate()
628 if (pin->bias <= PM8XXX_GPIO_BIAS_PU_1P5_30) in pm8xxx_pin_populate()
629 pin->pull_up_strength = pin->bias; in pm8xxx_pin_populate()
631 pin->pull_up_strength = PM8XXX_GPIO_BIAS_PU_30; in pm8xxx_pin_populate()
633 val = pm8xxx_read_bank(pctrl, pin, 3); in pm8xxx_pin_populate()
637 pin->output_strength = (val >> 2) & 0x3; in pm8xxx_pin_populate()
638 pin->disable = val & BIT(0); in pm8xxx_pin_populate()
640 val = pm8xxx_read_bank(pctrl, pin, 4); in pm8xxx_pin_populate()
644 pin->function = (val >> 1) & 0x7; in pm8xxx_pin_populate()
646 val = pm8xxx_read_bank(pctrl, pin, 5); in pm8xxx_pin_populate()
650 pin->inverted = !(val & BIT(3)); in pm8xxx_pin_populate()
670 .name = "ssbi-gpio",
686 struct pm8xxx_gpio *pctrl = container_of(domain->host_data, in pm8xxx_domain_translate()
689 if (fwspec->param_count != 2 || fwspec->param[0] < 1 || in pm8xxx_domain_translate()
690 fwspec->param[0] > pctrl->chip.ngpio) in pm8xxx_domain_translate()
691 return -EINVAL; in pm8xxx_domain_translate()
693 *hwirq = fwspec->param[0] - PM8XXX_GPIO_PHYSICAL_OFFSET; in pm8xxx_domain_translate()
694 *type = fwspec->param[1]; in pm8xxx_domain_translate()
718 { .compatible = "qcom,pm8018-gpio", .data = (void *) 6 },
719 { .compatible = "qcom,pm8038-gpio", .data = (void *) 12 },
720 { .compatible = "qcom,pm8058-gpio", .data = (void *) 44 },
721 { .compatible = "qcom,pm8917-gpio", .data = (void *) 38 },
722 { .compatible = "qcom,pm8921-gpio", .data = (void *) 44 },
737 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); in pm8xxx_gpio_probe()
739 return -ENOMEM; in pm8xxx_gpio_probe()
741 pctrl->dev = &pdev->dev; in pm8xxx_gpio_probe()
742 pctrl->npins = (uintptr_t) device_get_match_data(&pdev->dev); in pm8xxx_gpio_probe()
744 pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL); in pm8xxx_gpio_probe()
745 if (!pctrl->regmap) { in pm8xxx_gpio_probe()
746 dev_err(&pdev->dev, "parent regmap unavailable\n"); in pm8xxx_gpio_probe()
747 return -ENXIO; in pm8xxx_gpio_probe()
750 pctrl->desc = pm8xxx_pinctrl_desc; in pm8xxx_gpio_probe()
751 pctrl->desc.npins = pctrl->npins; in pm8xxx_gpio_probe()
753 pins = devm_kcalloc(&pdev->dev, in pm8xxx_gpio_probe()
754 pctrl->desc.npins, in pm8xxx_gpio_probe()
758 return -ENOMEM; in pm8xxx_gpio_probe()
760 pin_data = devm_kcalloc(&pdev->dev, in pm8xxx_gpio_probe()
761 pctrl->desc.npins, in pm8xxx_gpio_probe()
765 return -ENOMEM; in pm8xxx_gpio_probe()
767 for (i = 0; i < pctrl->desc.npins; i++) { in pm8xxx_gpio_probe()
778 pctrl->desc.pins = pins; in pm8xxx_gpio_probe()
780 pctrl->desc.num_custom_params = ARRAY_SIZE(pm8xxx_gpio_bindings); in pm8xxx_gpio_probe()
781 pctrl->desc.custom_params = pm8xxx_gpio_bindings; in pm8xxx_gpio_probe()
783 pctrl->desc.custom_conf_items = pm8xxx_conf_items; in pm8xxx_gpio_probe()
786 pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl); in pm8xxx_gpio_probe()
787 if (IS_ERR(pctrl->pctrl)) { in pm8xxx_gpio_probe()
788 dev_err(&pdev->dev, "couldn't register pm8xxx gpio driver\n"); in pm8xxx_gpio_probe()
789 return PTR_ERR(pctrl->pctrl); in pm8xxx_gpio_probe()
792 pctrl->chip = pm8xxx_gpio_template; in pm8xxx_gpio_probe()
793 pctrl->chip.base = -1; in pm8xxx_gpio_probe()
794 pctrl->chip.parent = &pdev->dev; in pm8xxx_gpio_probe()
795 pctrl->chip.of_gpio_n_cells = 2; in pm8xxx_gpio_probe()
796 pctrl->chip.label = dev_name(pctrl->dev); in pm8xxx_gpio_probe()
797 pctrl->chip.ngpio = pctrl->npins; in pm8xxx_gpio_probe()
799 parent_node = of_irq_find_parent(pctrl->dev->of_node); in pm8xxx_gpio_probe()
801 return -ENXIO; in pm8xxx_gpio_probe()
806 return -ENXIO; in pm8xxx_gpio_probe()
808 girq = &pctrl->chip.irq; in pm8xxx_gpio_probe()
810 girq->default_type = IRQ_TYPE_NONE; in pm8xxx_gpio_probe()
811 girq->handler = handle_level_irq; in pm8xxx_gpio_probe()
812 girq->fwnode = dev_fwnode(pctrl->dev); in pm8xxx_gpio_probe()
813 girq->parent_domain = parent_domain; in pm8xxx_gpio_probe()
814 girq->child_to_parent_hwirq = pm8xxx_child_to_parent_hwirq; in pm8xxx_gpio_probe()
815 girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell; in pm8xxx_gpio_probe()
816 girq->child_offset_to_irq = pm8xxx_child_offset_to_irq; in pm8xxx_gpio_probe()
817 girq->child_irq_domain_ops.translate = pm8xxx_domain_translate; in pm8xxx_gpio_probe()
819 ret = gpiochip_add_data(&pctrl->chip, pctrl); in pm8xxx_gpio_probe()
821 dev_err(&pdev->dev, "failed register gpiochip\n"); in pm8xxx_gpio_probe()
826 * For DeviceTree-supported systems, the gpio core checks the in pm8xxx_gpio_probe()
827 * pinctrl's device node for the "gpio-ranges" property. in pm8xxx_gpio_probe()
828 * If it is present, it takes care of adding the pin ranges in pm8xxx_gpio_probe()
832 * files which don't set the "gpio-ranges" property or systems that in pm8xxx_gpio_probe()
835 if (!of_property_read_bool(pctrl->dev->of_node, "gpio-ranges")) { in pm8xxx_gpio_probe()
836 ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), in pm8xxx_gpio_probe()
837 0, 0, pctrl->chip.ngpio); in pm8xxx_gpio_probe()
839 dev_err(pctrl->dev, "failed to add pin range\n"); in pm8xxx_gpio_probe()
846 dev_dbg(&pdev->dev, "Qualcomm pm8xxx gpio driver probed\n"); in pm8xxx_gpio_probe()
851 gpiochip_remove(&pctrl->chip); in pm8xxx_gpio_probe()
860 gpiochip_remove(&pctrl->chip); in pm8xxx_gpio_remove()
865 .name = "qcom-ssbi-gpio",