^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2015, Sony Mobile Communications AB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2013, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/pinctrl/pinmux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/pinctrl/pinconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/pinctrl/pinconf-generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "../core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "../pinctrl-utils.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define PM8XXX_GPIO_MODE_ENABLED BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define PM8XXX_GPIO_MODE_INPUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define PM8XXX_GPIO_MODE_OUTPUT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* output buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PM8XXX_GPIO_PUSH_PULL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PM8XXX_GPIO_OPEN_DRAIN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* bias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define PM8XXX_GPIO_BIAS_PU_30 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define PM8XXX_GPIO_BIAS_PU_1P5 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define PM8XXX_GPIO_BIAS_PU_31P5 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define PM8XXX_GPIO_BIAS_PU_1P5_30 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PM8XXX_GPIO_BIAS_PD 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PM8XXX_GPIO_BIAS_NP 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* GPIO registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define SSBI_REG_ADDR_GPIO_BASE 0x150
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SSBI_REG_ADDR_GPIO(n) (SSBI_REG_ADDR_GPIO_BASE + n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define PM8XXX_BANK_WRITE BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PM8XXX_MAX_GPIOS 44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define PM8XXX_GPIO_PHYSICAL_OFFSET 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* custom pinconf parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PM8XXX_QCOM_DRIVE_STRENGH (PIN_CONFIG_END + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define PM8XXX_QCOM_PULL_UP_STRENGTH (PIN_CONFIG_END + 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * struct pm8xxx_pin_data - dynamic configuration for a pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @reg: address of the control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @power_source: logical selected voltage source, mapping in static data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * is used translate to register values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @mode: operating mode for the pin (input/output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * @open_drain: output buffer configured as open-drain (vs push-pull)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @output_value: configured output value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * @bias: register view of configured bias
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * @pull_up_strength: placeholder for selected pull up strength
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * only used to configure bias when pull up is selected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * @output_strength: selector of output-strength
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @disable: pin disabled / configured as tristate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * @function: pinmux selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * @inverted: pin logic is inverted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct pm8xxx_pin_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u8 power_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) bool open_drain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) bool output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u8 bias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u8 pull_up_strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u8 output_strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) bool disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) u8 function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) bool inverted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct pm8xxx_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct pinctrl_dev *pctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct gpio_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct pinctrl_desc desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static const struct pinconf_generic_params pm8xxx_gpio_bindings[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {"qcom,drive-strength", PM8XXX_QCOM_DRIVE_STRENGH, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {"qcom,pull-up-strength", PM8XXX_QCOM_PULL_UP_STRENGTH, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static const struct pin_config_item pm8xxx_conf_items[ARRAY_SIZE(pm8xxx_gpio_bindings)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) PCONFDUMP(PM8XXX_QCOM_DRIVE_STRENGH, "drive-strength", NULL, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) PCONFDUMP(PM8XXX_QCOM_PULL_UP_STRENGTH, "pull up strength", NULL, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static const char * const pm8xxx_groups[PM8XXX_MAX_GPIOS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", "gpio15",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", "gpio22",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", "gpio36",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", "gpio43",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) "gpio44",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static const char * const pm8xxx_gpio_functions[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) PMIC_GPIO_FUNC_NORMAL, PMIC_GPIO_FUNC_PAIRED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) PMIC_GPIO_FUNC_FUNC1, PMIC_GPIO_FUNC_FUNC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) PMIC_GPIO_FUNC_DTEST1, PMIC_GPIO_FUNC_DTEST2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) PMIC_GPIO_FUNC_DTEST3, PMIC_GPIO_FUNC_DTEST4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int pm8xxx_read_bank(struct pm8xxx_gpio *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct pm8xxx_pin_data *pin, int bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) unsigned int val = bank << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ret = regmap_write(pctrl->regmap, pin->reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) dev_err(pctrl->dev, "failed to select bank %d\n", bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ret = regmap_read(pctrl->regmap, pin->reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dev_err(pctrl->dev, "failed to read register %d\n", bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static int pm8xxx_write_bank(struct pm8xxx_gpio *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct pm8xxx_pin_data *pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int bank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) val |= PM8XXX_BANK_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) val |= bank << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ret = regmap_write(pctrl->regmap, pin->reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) dev_err(pctrl->dev, "failed to write register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int pm8xxx_get_groups_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return pctrl->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static const char *pm8xxx_get_group_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return pm8xxx_groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int pm8xxx_get_group_pins(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) unsigned group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) const unsigned **pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) unsigned *num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) *pins = &pctrl->desc.pins[group].number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) *num_pins = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static const struct pinctrl_ops pm8xxx_pinctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .get_groups_count = pm8xxx_get_groups_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .get_group_name = pm8xxx_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .get_group_pins = pm8xxx_get_group_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .dt_free_map = pinctrl_utils_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int pm8xxx_get_functions_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return ARRAY_SIZE(pm8xxx_gpio_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static const char *pm8xxx_get_function_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) unsigned function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return pm8xxx_gpio_functions[function];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static int pm8xxx_get_function_groups(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) const char * const **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned * const num_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) *groups = pm8xxx_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) *num_groups = pctrl->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static int pm8xxx_pinmux_set_mux(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct pm8xxx_pin_data *pin = pctrl->desc.pins[group].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) pin->function = function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) val = pin->function << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) pm8xxx_write_bank(pctrl, pin, 4, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static const struct pinmux_ops pm8xxx_pinmux_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) .get_functions_count = pm8xxx_get_functions_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) .get_function_name = pm8xxx_get_function_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) .get_function_groups = pm8xxx_get_function_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) .set_mux = pm8xxx_pinmux_set_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int pm8xxx_pin_config_get(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) unsigned param = pinconf_to_config_param(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) unsigned arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (pin->bias != PM8XXX_GPIO_BIAS_NP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) arg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (pin->bias != PM8XXX_GPIO_BIAS_PD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) arg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (pin->bias > PM8XXX_GPIO_BIAS_PU_1P5_30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) arg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case PM8XXX_QCOM_PULL_UP_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) arg = pin->pull_up_strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!pin->disable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) arg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case PIN_CONFIG_INPUT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (pin->mode != PM8XXX_GPIO_MODE_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) arg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case PIN_CONFIG_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (pin->mode & PM8XXX_GPIO_MODE_OUTPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) arg = pin->output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) arg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) case PIN_CONFIG_POWER_SOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) arg = pin->power_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case PM8XXX_QCOM_DRIVE_STRENGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) arg = pin->output_strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) case PIN_CONFIG_DRIVE_PUSH_PULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (pin->open_drain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) arg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case PIN_CONFIG_DRIVE_OPEN_DRAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!pin->open_drain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) arg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) *config = pinconf_to_config_packed(param, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static int pm8xxx_pin_config_set(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) unsigned long *configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) unsigned param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) unsigned arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) u8 banks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) for (i = 0; i < num_configs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) param = pinconf_to_config_param(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) arg = pinconf_to_config_argument(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) pin->bias = PM8XXX_GPIO_BIAS_NP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) banks |= BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) pin->disable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) banks |= BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) pin->bias = PM8XXX_GPIO_BIAS_PD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) banks |= BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) pin->disable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) banks |= BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) case PM8XXX_QCOM_PULL_UP_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (arg > PM8XXX_GPIO_BIAS_PU_1P5_30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) dev_err(pctrl->dev, "invalid pull-up strength\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) pin->pull_up_strength = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) pin->bias = pin->pull_up_strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) banks |= BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) pin->disable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) banks |= BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) pin->disable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) banks |= BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case PIN_CONFIG_INPUT_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) pin->mode = PM8XXX_GPIO_MODE_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) banks |= BIT(0) | BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) case PIN_CONFIG_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) pin->mode = PM8XXX_GPIO_MODE_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) pin->output_value = !!arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) banks |= BIT(0) | BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) case PIN_CONFIG_POWER_SOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) pin->power_source = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) banks |= BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) case PM8XXX_QCOM_DRIVE_STRENGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (arg > PMIC_GPIO_STRENGTH_LOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) dev_err(pctrl->dev, "invalid drive strength\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) pin->output_strength = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) banks |= BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case PIN_CONFIG_DRIVE_PUSH_PULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) pin->open_drain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) banks |= BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case PIN_CONFIG_DRIVE_OPEN_DRAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) pin->open_drain = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) banks |= BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) dev_err(pctrl->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) "unsupported config parameter: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (banks & BIT(0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) val = pin->power_source << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) val |= PM8XXX_GPIO_MODE_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) pm8xxx_write_bank(pctrl, pin, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (banks & BIT(1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) val = pin->mode << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) val |= pin->open_drain << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) val |= pin->output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) pm8xxx_write_bank(pctrl, pin, 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (banks & BIT(2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) val = pin->bias << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pm8xxx_write_bank(pctrl, pin, 2, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (banks & BIT(3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) val = pin->output_strength << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) val |= pin->disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) pm8xxx_write_bank(pctrl, pin, 3, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (banks & BIT(4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) val = pin->function << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) pm8xxx_write_bank(pctrl, pin, 4, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (banks & BIT(5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (!pin->inverted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) val |= BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) pm8xxx_write_bank(pctrl, pin, 5, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static const struct pinconf_ops pm8xxx_pinconf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .is_generic = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .pin_config_group_get = pm8xxx_pin_config_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .pin_config_group_set = pm8xxx_pin_config_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static const struct pinctrl_desc pm8xxx_pinctrl_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .name = "pm8xxx_gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .pctlops = &pm8xxx_pinctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) .pmxops = &pm8xxx_pinmux_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .confops = &pm8xxx_pinconf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static int pm8xxx_gpio_direction_input(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) pin->mode = PM8XXX_GPIO_MODE_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) val = pin->mode << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) pm8xxx_write_bank(pctrl, pin, 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static int pm8xxx_gpio_direction_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) unsigned offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) pin->mode = PM8XXX_GPIO_MODE_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) pin->output_value = !!value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) val = pin->mode << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) val |= pin->open_drain << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) val |= pin->output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) pm8xxx_write_bank(pctrl, pin, 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int pm8xxx_gpio_get(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) int ret, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) bool state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return pin->output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) irq = chip->to_irq(chip, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (irq >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ret = irq_get_irqchip_state(irq, IRQCHIP_STATE_LINE_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = !!state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static void pm8xxx_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) pin->output_value = !!value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) val = pin->mode << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) val |= pin->open_drain << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) val |= pin->output_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) pm8xxx_write_bank(pctrl, pin, 1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int pm8xxx_gpio_of_xlate(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) const struct of_phandle_args *gpio_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) u32 *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (chip->of_gpio_n_cells < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) *flags = gpio_desc->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return gpio_desc->args[0] - PM8XXX_GPIO_PHYSICAL_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void pm8xxx_gpio_dbg_show_one(struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) unsigned offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) unsigned gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static const char * const modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) "in", "both", "out", "off"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static const char * const biases[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) "pull-up 30uA", "pull-up 1.5uA", "pull-up 31.5uA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) "pull-up 1.5uA + 30uA boost", "pull-down 10uA", "no pull"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static const char * const buffer_types[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) "push-pull", "open-drain"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static const char * const strengths[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) "no", "high", "medium", "low"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) seq_printf(s, " gpio%-2d:", offset + PM8XXX_GPIO_PHYSICAL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (pin->disable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) seq_puts(s, " ---");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) seq_printf(s, " %-4s", modes[pin->mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) seq_printf(s, " %-7s", pm8xxx_gpio_functions[pin->function]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) seq_printf(s, " VIN%d", pin->power_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) seq_printf(s, " %-27s", biases[pin->bias]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) seq_printf(s, " %-10s", buffer_types[pin->open_drain]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) seq_printf(s, " %-4s", pin->output_value ? "high" : "low");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) seq_printf(s, " %-7s", strengths[pin->output_strength]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (pin->inverted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) seq_puts(s, " inverted");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static void pm8xxx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) unsigned gpio = chip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) for (i = 0; i < chip->ngpio; i++, gpio++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) pm8xxx_gpio_dbg_show_one(s, NULL, chip, i, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) seq_puts(s, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) #define pm8xxx_gpio_dbg_show NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static const struct gpio_chip pm8xxx_gpio_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .direction_input = pm8xxx_gpio_direction_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .direction_output = pm8xxx_gpio_direction_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) .get = pm8xxx_gpio_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) .set = pm8xxx_gpio_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .of_xlate = pm8xxx_gpio_of_xlate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) .dbg_show = pm8xxx_gpio_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static int pm8xxx_pin_populate(struct pm8xxx_gpio *pctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct pm8xxx_pin_data *pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) val = pm8xxx_read_bank(pctrl, pin, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) pin->power_source = (val >> 1) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) val = pm8xxx_read_bank(pctrl, pin, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) pin->mode = (val >> 2) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) pin->open_drain = !!(val & BIT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) pin->output_value = val & BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) val = pm8xxx_read_bank(pctrl, pin, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) pin->bias = (val >> 1) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (pin->bias <= PM8XXX_GPIO_BIAS_PU_1P5_30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) pin->pull_up_strength = pin->bias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) pin->pull_up_strength = PM8XXX_GPIO_BIAS_PU_30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) val = pm8xxx_read_bank(pctrl, pin, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) pin->output_strength = (val >> 2) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) pin->disable = val & BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) val = pm8xxx_read_bank(pctrl, pin, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) pin->function = (val >> 1) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) val = pm8xxx_read_bank(pctrl, pin, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) pin->inverted = !(val & BIT(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static struct irq_chip pm8xxx_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) .name = "ssbi-gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) .irq_mask_ack = irq_chip_mask_ack_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) .irq_unmask = irq_chip_unmask_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) .irq_set_type = irq_chip_set_type_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static int pm8xxx_domain_translate(struct irq_domain *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct irq_fwspec *fwspec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) unsigned long *hwirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) unsigned int *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) struct pm8xxx_gpio *pctrl = container_of(domain->host_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct pm8xxx_gpio, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (fwspec->param_count != 2 || fwspec->param[0] < 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) fwspec->param[0] > pctrl->chip.ngpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) *hwirq = fwspec->param[0] - PM8XXX_GPIO_PHYSICAL_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) *type = fwspec->param[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static unsigned int pm8xxx_child_offset_to_irq(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return offset + PM8XXX_GPIO_PHYSICAL_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static int pm8xxx_child_to_parent_hwirq(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) unsigned int child_hwirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) unsigned int child_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) unsigned int *parent_hwirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) unsigned int *parent_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) *parent_hwirq = child_hwirq + 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) *parent_type = child_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static const struct of_device_id pm8xxx_gpio_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) { .compatible = "qcom,pm8018-gpio", .data = (void *) 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) { .compatible = "qcom,pm8038-gpio", .data = (void *) 12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) { .compatible = "qcom,pm8058-gpio", .data = (void *) 44 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) { .compatible = "qcom,pm8917-gpio", .data = (void *) 38 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) { .compatible = "qcom,pm8921-gpio", .data = (void *) 44 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) MODULE_DEVICE_TABLE(of, pm8xxx_gpio_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static int pm8xxx_gpio_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct pm8xxx_pin_data *pin_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct irq_domain *parent_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct device_node *parent_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct pinctrl_pin_desc *pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct gpio_irq_chip *girq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct pm8xxx_gpio *pctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (!pctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) pctrl->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) pctrl->npins = (uintptr_t) device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (!pctrl->regmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) dev_err(&pdev->dev, "parent regmap unavailable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) pctrl->desc = pm8xxx_pinctrl_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) pctrl->desc.npins = pctrl->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) pins = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) pctrl->desc.npins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) sizeof(struct pinctrl_pin_desc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (!pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) pin_data = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) pctrl->desc.npins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) sizeof(struct pm8xxx_pin_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (!pin_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) for (i = 0; i < pctrl->desc.npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) pin_data[i].reg = SSBI_REG_ADDR_GPIO(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) ret = pm8xxx_pin_populate(pctrl, &pin_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) pins[i].number = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) pins[i].name = pm8xxx_groups[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) pins[i].drv_data = &pin_data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) pctrl->desc.pins = pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) pctrl->desc.num_custom_params = ARRAY_SIZE(pm8xxx_gpio_bindings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) pctrl->desc.custom_params = pm8xxx_gpio_bindings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) pctrl->desc.custom_conf_items = pm8xxx_conf_items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (IS_ERR(pctrl->pctrl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) dev_err(&pdev->dev, "couldn't register pm8xxx gpio driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return PTR_ERR(pctrl->pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) pctrl->chip = pm8xxx_gpio_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) pctrl->chip.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) pctrl->chip.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) pctrl->chip.of_node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) pctrl->chip.of_gpio_n_cells = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) pctrl->chip.label = dev_name(pctrl->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) pctrl->chip.ngpio = pctrl->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) parent_node = of_irq_find_parent(pctrl->dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (!parent_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) parent_domain = irq_find_host(parent_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) of_node_put(parent_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (!parent_domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) girq = &pctrl->chip.irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) girq->chip = &pm8xxx_irq_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) girq->default_type = IRQ_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) girq->handler = handle_level_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) girq->fwnode = of_node_to_fwnode(pctrl->dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) girq->parent_domain = parent_domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) girq->child_to_parent_hwirq = pm8xxx_child_to_parent_hwirq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) girq->child_offset_to_irq = pm8xxx_child_offset_to_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) girq->child_irq_domain_ops.translate = pm8xxx_domain_translate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ret = gpiochip_add_data(&pctrl->chip, pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) dev_err(&pdev->dev, "failed register gpiochip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * For DeviceTree-supported systems, the gpio core checks the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * pinctrl's device node for the "gpio-ranges" property.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * If it is present, it takes care of adding the pin ranges
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * for the driver. In this case the driver can skip ahead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * In order to remain compatible with older, existing DeviceTree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * files which don't set the "gpio-ranges" property or systems that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * utilize ACPI the driver has to call gpiochip_add_pin_range().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (!of_property_read_bool(pctrl->dev->of_node, "gpio-ranges")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 0, 0, pctrl->chip.ngpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) dev_err(pctrl->dev, "failed to add pin range\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) goto unregister_gpiochip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) platform_set_drvdata(pdev, pctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) dev_dbg(&pdev->dev, "Qualcomm pm8xxx gpio driver probed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) unregister_gpiochip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) gpiochip_remove(&pctrl->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) static int pm8xxx_gpio_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct pm8xxx_gpio *pctrl = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) gpiochip_remove(&pctrl->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static struct platform_driver pm8xxx_gpio_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .name = "qcom-ssbi-gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .of_match_table = pm8xxx_gpio_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .probe = pm8xxx_gpio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) .remove = pm8xxx_gpio_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) module_platform_driver(pm8xxx_gpio_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) MODULE_DESCRIPTION("Qualcomm PM8xxx GPIO driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) MODULE_LICENSE("GPL v2");