Lines Matching +full:pin +full:- +full:val
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
17 #include <linux/pinctrl/pinconf-generic.h>
21 #include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
24 #include "../pinctrl-utils.h"
29 * Pull Up Values - it indicates whether a pull-up should be
100 /* Qualcomm specific pin configurations */
107 * struct pmic_mpp_pad - keep current MPP settings
110 * @out_value: Cached pin output value.
113 * @paired: Pin operates in paired mode
114 * @has_pullup: Pin has support to configure pullup
115 * @num_sources: Number of power-sources supported by this MPP.
116 * @power_source: Current power-source used.
150 {"qcom,amux-route", PMIC_MPP_CONF_AMUX_ROUTE, 0},
151 {"qcom,analog-level", PMIC_MPP_CONF_ANALOG_LEVEL, 0},
180 unsigned int val;
183 ret = regmap_read(state->map, pad->base + addr, &val);
185 dev_err(state->dev, "read 0x%x failed\n", addr);
187 ret = val;
194 unsigned int val)
198 ret = regmap_write(state->map, pad->base + addr, val);
200 dev_err(state->dev, "write 0x%x failed\n", addr);
207 /* Every PIN is a group */
208 return pctldev->desc->npins;
212 unsigned pin)
214 return pctldev->desc->pins[pin].name;
218 unsigned pin,
221 *pins = &pctldev->desc->pins[pin].number;
251 *num_qgroups = pctldev->desc->npins;
260 unsigned int val;
263 switch (pad->function) {
265 if (pad->input_enabled && pad->output_enabled)
267 else if (pad->input_enabled)
273 if (pad->input_enabled && pad->output_enabled)
275 else if (pad->input_enabled)
286 if (pad->dtest)
287 sel = PMIC_MPP_SELECTOR_DTEST_FIRST + pad->dtest - 1;
288 else if (pad->paired)
293 en = !!pad->out_value;
295 val = mode << PMIC_MPP_REG_MODE_DIR_SHIFT |
299 return pmic_mpp_write(state, pad, PMIC_MPP_REG_MODE_CTL, val);
303 unsigned pin)
307 unsigned int val;
310 pad = pctldev->desc->pins[pin].drv_data;
312 pad->function = function;
318 val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT;
320 return pmic_mpp_write(state, pad, PMIC_MPP_REG_EN_CTL, val);
331 unsigned int pin, unsigned long *config)
337 pad = pctldev->desc->pins[pin].drv_data;
341 if (pad->pullup != PMIC_MPP_PULL_UP_OPEN)
342 return -EINVAL;
346 switch (pad->pullup) {
357 return -EINVAL;
361 if (pad->is_enabled)
362 return -EINVAL;
366 arg = pad->power_source;
369 if (!pad->input_enabled)
370 return -EINVAL;
374 arg = pad->out_value;
377 arg = pad->dtest;
380 arg = pad->amux_input;
383 if (!pad->paired)
384 return -EINVAL;
388 arg = pad->drive_strength;
391 arg = pad->aout_level;
394 return -EINVAL;
402 static int pmic_mpp_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
408 unsigned int val;
411 pad = pctldev->desc->pins[pin].drv_data;
413 /* Make it possible to enable the pin, by not setting high impedance */
414 pad->is_enabled = true;
422 pad->pullup = PMIC_MPP_PULL_UP_OPEN;
427 pad->pullup = PMIC_MPP_PULL_UP_0P6KOHM;
430 pad->pullup = PMIC_MPP_PULL_UP_10KOHM;
433 pad->pullup = PMIC_MPP_PULL_UP_30KOHM;
436 return -EINVAL;
440 pad->is_enabled = false;
443 if (arg >= pad->num_sources)
444 return -EINVAL;
445 pad->power_source = arg;
448 pad->input_enabled = arg ? true : false;
451 pad->output_enabled = true;
452 pad->out_value = arg;
455 pad->dtest = arg;
458 pad->drive_strength = arg;
462 return -EINVAL;
463 pad->amux_input = arg;
466 pad->aout_level = arg;
469 pad->paired = !!arg;
472 return -EINVAL;
476 val = pad->power_source << PMIC_MPP_REG_VIN_SHIFT;
478 ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_DIG_VIN_CTL, val);
482 if (pad->has_pullup) {
483 val = pad->pullup << PMIC_MPP_REG_PULL_SHIFT;
486 val);
491 val = pad->amux_input & PMIC_MPP_REG_AIN_ROUTE_MASK;
493 ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_AIN_CTL, val);
497 ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_AOUT_CTL, pad->aout_level);
505 ret = pmic_mpp_write(state, pad, PMIC_MPP_REG_SINK_CTL, pad->drive_strength);
509 val = pad->is_enabled << PMIC_MPP_REG_MASTER_EN_SHIFT;
511 return pmic_mpp_write(state, pad, PMIC_MPP_REG_EN_CTL, val);
515 struct seq_file *s, unsigned pin)
525 pad = pctldev->desc->pins[pin].drv_data;
527 seq_printf(s, " mpp%-2d:", pin + PMIC_MPP_PHYSICAL_OFFSET);
529 if (!pad->is_enabled) {
530 seq_puts(s, " ---");
533 if (pad->input_enabled) {
539 pad->out_value = ret;
542 seq_printf(s, " %-4s", pad->output_enabled ? "out" : "in");
543 seq_printf(s, " %-7s", pmic_mpp_functions[pad->function]);
544 seq_printf(s, " vin-%d", pad->power_source);
545 seq_printf(s, " %d", pad->aout_level);
546 if (pad->has_pullup)
547 seq_printf(s, " %-8s", biases[pad->pullup]);
548 seq_printf(s, " %-4s", str_high_low(pad->out_value));
549 if (pad->dtest)
550 seq_printf(s, " dtest%d", pad->dtest);
551 if (pad->paired)
563 static int pmic_mpp_direction_input(struct gpio_chip *chip, unsigned pin)
570 return pmic_mpp_config_set(state->ctrl, pin, &config, 1);
574 unsigned pin, int val)
579 config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val);
581 return pmic_mpp_config_set(state->ctrl, pin, &config, 1);
584 static int pmic_mpp_get(struct gpio_chip *chip, unsigned pin)
590 pad = state->ctrl->desc->pins[pin].drv_data;
592 if (pad->input_enabled) {
597 pad->out_value = ret & PMIC_MPP_REG_RT_STS_VAL_MASK;
600 return !!pad->out_value;
603 static void pmic_mpp_set(struct gpio_chip *chip, unsigned pin, int value)
610 pmic_mpp_config_set(state->ctrl, pin, &config, 1);
617 if (chip->of_gpio_n_cells < 2)
618 return -EINVAL;
621 *flags = gpio_desc->args[1];
623 return gpio_desc->args[0] - PMIC_MPP_PHYSICAL_OFFSET;
631 for (i = 0; i < chip->ngpio; i++) {
632 pmic_mpp_config_dbg_show(state->ctrl, s, i);
651 int type, subtype, val, dir;
659 dev_err(state->dev, "incorrect block type 0x%x at 0x%x\n",
660 type, pad->base);
661 return -ENODEV;
674 pad->num_sources = 4;
677 pad->num_sources = 8;
680 dev_err(state->dev, "unknown MPP type 0x%x at 0x%x\n",
681 subtype, pad->base);
682 return -ENODEV;
685 val = pmic_mpp_read(state, pad, PMIC_MPP_REG_MODE_CTL);
686 if (val < 0)
687 return val;
689 pad->out_value = val & PMIC_MPP_REG_MODE_VALUE_MASK;
691 dir = val >> PMIC_MPP_REG_MODE_DIR_SHIFT;
696 pad->input_enabled = true;
697 pad->output_enabled = false;
698 pad->function = PMIC_MPP_DIGITAL;
701 pad->input_enabled = false;
702 pad->output_enabled = true;
703 pad->function = PMIC_MPP_DIGITAL;
706 pad->input_enabled = true;
707 pad->output_enabled = true;
708 pad->function = PMIC_MPP_DIGITAL;
711 pad->input_enabled = true;
712 pad->output_enabled = true;
713 pad->function = PMIC_MPP_ANALOG;
716 pad->input_enabled = true;
717 pad->output_enabled = false;
718 pad->function = PMIC_MPP_ANALOG;
721 pad->input_enabled = false;
722 pad->output_enabled = true;
723 pad->function = PMIC_MPP_ANALOG;
726 pad->input_enabled = false;
727 pad->output_enabled = true;
728 pad->function = PMIC_MPP_SINK;
731 dev_err(state->dev, "unknown MPP direction\n");
732 return -ENODEV;
735 sel = val >> PMIC_MPP_REG_MODE_FUNCTION_SHIFT;
739 pad->dtest = sel + 1;
741 pad->paired = true;
743 val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_VIN_CTL);
744 if (val < 0)
745 return val;
747 pad->power_source = val >> PMIC_MPP_REG_VIN_SHIFT;
748 pad->power_source &= PMIC_MPP_REG_VIN_MASK;
752 val = pmic_mpp_read(state, pad, PMIC_MPP_REG_DIG_PULL_CTL);
753 if (val < 0)
754 return val;
756 pad->pullup = val >> PMIC_MPP_REG_PULL_SHIFT;
757 pad->pullup &= PMIC_MPP_REG_PULL_MASK;
758 pad->has_pullup = true;
761 val = pmic_mpp_read(state, pad, PMIC_MPP_REG_AIN_CTL);
762 if (val < 0)
763 return val;
765 pad->amux_input = val >> PMIC_MPP_REG_AIN_ROUTE_SHIFT;
766 pad->amux_input &= PMIC_MPP_REG_AIN_ROUTE_MASK;
768 val = pmic_mpp_read(state, pad, PMIC_MPP_REG_SINK_CTL);
769 if (val < 0)
770 return val;
772 pad->drive_strength = val;
774 val = pmic_mpp_read(state, pad, PMIC_MPP_REG_AOUT_CTL);
775 if (val < 0)
776 return val;
778 pad->aout_level = val;
780 val = pmic_mpp_read(state, pad, PMIC_MPP_REG_EN_CTL);
781 if (val < 0)
782 return val;
784 pad->is_enabled = !!val;
794 struct pmic_mpp_state *state = container_of(domain->host_data,
798 if (fwspec->param_count != 2 ||
799 fwspec->param[0] < 1 || fwspec->param[0] > state->chip.ngpio)
800 return -EINVAL;
802 *hwirq = fwspec->param[0] - PMIC_MPP_PHYSICAL_OFFSET;
803 *type = fwspec->param[1];
843 .name = "spmi-mpp",
857 struct device *dev = &pdev->dev;
866 ret = of_property_read_u32(dev->of_node, "reg", ®);
872 npins = (uintptr_t) device_get_match_data(&pdev->dev);
878 return -ENOMEM;
882 state->dev = &pdev->dev;
883 state->map = dev_get_regmap(dev->parent, NULL);
887 return -ENOMEM;
891 return -ENOMEM;
895 return -ENOMEM;
897 pctrldesc->pctlops = &pmic_mpp_pinctrl_ops;
898 pctrldesc->pmxops = &pmic_mpp_pinmux_ops;
899 pctrldesc->confops = &pmic_mpp_pinconf_ops;
900 pctrldesc->owner = THIS_MODULE;
901 pctrldesc->name = dev_name(dev);
902 pctrldesc->pins = pindesc;
903 pctrldesc->npins = npins;
905 pctrldesc->num_custom_params = ARRAY_SIZE(pmic_mpp_bindings);
906 pctrldesc->custom_params = pmic_mpp_bindings;
908 pctrldesc->custom_conf_items = pmic_conf_items;
913 pindesc->drv_data = pad;
914 pindesc->number = i;
915 pindesc->name = pmic_mpp_groups[i];
917 pad->base = reg + i * PMIC_MPP_ADDRESS_RANGE;
924 state->chip = pmic_mpp_gpio_template;
925 state->chip.parent = dev;
926 state->chip.base = -1;
927 state->chip.ngpio = npins;
928 state->chip.label = dev_name(dev);
929 state->chip.of_gpio_n_cells = 2;
930 state->chip.can_sleep = false;
932 state->ctrl = devm_pinctrl_register(dev, pctrldesc, state);
933 if (IS_ERR(state->ctrl))
934 return PTR_ERR(state->ctrl);
936 parent_node = of_irq_find_parent(state->dev->of_node);
938 return -ENXIO;
943 return -ENXIO;
945 girq = &state->chip.irq;
947 girq->default_type = IRQ_TYPE_NONE;
948 girq->handler = handle_level_irq;
949 girq->fwnode = dev_fwnode(state->dev);
950 girq->parent_domain = parent_domain;
951 girq->child_to_parent_hwirq = pmic_mpp_child_to_parent_hwirq;
952 girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell;
953 girq->child_offset_to_irq = pmic_mpp_child_offset_to_irq;
954 girq->child_irq_domain_ops.translate = pmic_mpp_domain_translate;
956 ret = gpiochip_add_data(&state->chip, state);
958 dev_err(state->dev, "can't add gpio chip\n");
962 ret = gpiochip_add_pin_range(&state->chip, dev_name(dev), 0, 0, npins);
964 dev_err(dev, "failed to add pin range\n");
971 gpiochip_remove(&state->chip);
979 gpiochip_remove(&state->chip);
983 { .compatible = "qcom,pm8019-mpp", .data = (void *) 6 },
984 { .compatible = "qcom,pm8226-mpp", .data = (void *) 8 },
985 { .compatible = "qcom,pm8841-mpp", .data = (void *) 4 },
986 { .compatible = "qcom,pm8916-mpp", .data = (void *) 4 },
987 { .compatible = "qcom,pm8937-mpp", .data = (void *) 4 },
988 { .compatible = "qcom,pm8941-mpp", .data = (void *) 8 },
989 { .compatible = "qcom,pm8950-mpp", .data = (void *) 4 },
990 { .compatible = "qcom,pmi8950-mpp", .data = (void *) 4 },
991 { .compatible = "qcom,pm8994-mpp", .data = (void *) 8 },
992 { .compatible = "qcom,pma8084-mpp", .data = (void *) 8 },
993 { .compatible = "qcom,pmi8994-mpp", .data = (void *) 4 },
1001 .name = "qcom-spmi-mpp",
1010 MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
1011 MODULE_DESCRIPTION("Qualcomm SPMI PMIC MPP pin control driver");
1012 MODULE_ALIAS("platform:qcom-spmi-mpp");