gpio: qpnp-gpio: Update driver to match new hardware specification
The software / hardware interface for the qpnp gpio block has
changed. Update the driver to match the new interface. Also
improve error handling where possible. No change in the feature
set is introduced by this modification.
Change-Id: I9d4c6a10296de86e3cf6f3b4c2006ed81353f58f
Signed-off-by: Michael Bohan <mbohan@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/gpio/qpnp-gpio.txt b/Documentation/devicetree/bindings/gpio/qpnp-gpio.txt
index dff6a3e..a699a17 100644
--- a/Documentation/devicetree/bindings/gpio/qpnp-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/qpnp-gpio.txt
@@ -34,16 +34,20 @@
@direction: indicates whether the gpio should be input, output, or
both.
+ QPNP_GPIO_DIR_IN = 0,
QPNP_GPIO_DIR_OUT = 1,
- QPNP_GPIO_DIR_IN = 2,
- QPNP_GPIO_DIR_BOTH = 3
+ QPNP_GPIO_DIR_BOTH = 2
@output_type: indicates gpio should be configured as CMOS or open
drain.
- QPNP_GPIO_OUT_BUF_OPEN_DRAIN = 1,
QPNP_GPIO_OUT_BUF_CMOS = 0
+ QPNP_GPIO_OUT_BUF_OPEN_DRAIN_NMOS = 1,
+ QPNP_GPIO_OUT_BUF_OPEN_DRAIN_PMOS = 2,
- @output_value: The gpio output value of the gpio line - 0 or 1
+ @invert: Invert the signal of the gpio line -
+ QPNP_GPIO_INVERT_DISABLE = 0
+ QPNP_GPIO_INVERT_ENABLE = 1
+
@pull: Indicates whether a pull up or pull down should be
applied. If a pullup is required the current strength
needs to be specified. Current values of 30uA, 1.5uA,
@@ -68,9 +72,9 @@
QPNP_GPIO_VIN7 = 7
@out_strength: the amount of current supplied for an output gpio.
- QPNP_GPIO_OUT_STRENGTH_HIGH = 1,
+ QPNP_GPIO_OUT_STRENGTH_LOW = 1
QPNP_GPIO_OUT_STRENGTH_MED = 2,
- QPNP_GPIO_OUT_STRENGTH_LOW = 3
+ QPNP_GPIO_OUT_STRENGTH_HIGH = 3,
@source_sel: choose alternate function for the gpio. Certain gpios
can be paired (shorted) with each other. Some gpio pin
@@ -78,16 +82,17 @@
QPNP_GPIO_FUNC_NORMAL = 0,
QPNP_GPIO_FUNC_PAIRED = 1
QPNP_GPIO_FUNC_1 = 2,
- QPNP_GPIO_FUNC_3 = 3,
+ QPNP_GPIO_FUNC_2 = 3,
QPNP_GPIO_DTEST1 = 4,
QPNP_GPIO_DTEST2 = 5,
QPNP_GPIO_DTEST3 = 6,
QPNP_GPIO_DTEST4 = 7
- @master_en: 1 = Enable features within the GPIO block based on
- configurations.
- 0 = Completely disable the GPIO block and let the pin
- float with high impedance regardless of other settings.
+ @master_en: 1 = Enable features within the
+ GPIO block based on configurations.
+ 0 = Completely disable the GPIO
+ block and let the pin float with high impedance
+ regardless of other settings.
[PMIC GPIO clients]
diff --git a/drivers/gpio/qpnp-gpio.c b/drivers/gpio/qpnp-gpio.c
index 90cc798..ab2e8ef 100644
--- a/drivers/gpio/qpnp-gpio.c
+++ b/drivers/gpio/qpnp-gpio.c
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/spmi.h>
@@ -27,49 +29,80 @@
((q_spec)->offset + reg_index)
#define Q_REG_STATUS1 0x8
-#define Q_NUM_CTL_REGS 5
+#define Q_NUM_CTL_REGS 7
+
+/* type registers base address offsets */
+#define Q_REG_TYPE 0x10
+#define Q_REG_SUBTYPE 0x11
+
+/* gpio peripheral type and subtype values */
+#define Q_GPIO_TYPE 0x10
+#define Q_GPIO_SUBTYPE_GPIO_4CH 0x1
+#define Q_GPIO_SUBTYPE_GPIOC_4CH 0x5
+#define Q_GPIO_SUBTYPE_GPIO_8CH 0x9
+#define Q_GPIO_SUBTYPE_GPIOC_8CH 0xD
/* control register base address offsets */
-#define Q_REG_IO_CTL1 0x42
-#define Q_REG_INPUT_CTL1 0x43
-#define Q_REG_OUTPUT_CTL1 0x44
-#define Q_REG_OUTPUT_CTL2 0x45
-#define Q_REG_EN_CTL1 0x46
+#define Q_REG_MODE_CTL 0x40
+#define Q_REG_DIG_PULL_CTL 0x42
+#define Q_REG_DIG_IN_CTL 0x43
+#define Q_REG_DIG_VIN_CTL 0x44
+#define Q_REG_DIG_OUT_CTL 0x45
+#define Q_REG_EN_CTL 0x46
/* control register regs array indices */
-#define Q_REG_I_IO_CTL1 0
-#define Q_REG_I_INPUT_CTL1 1
-#define Q_REG_I_OUTPUT_CTL1 2
-#define Q_REG_I_OUTPUT_CTL2 3
-#define Q_REG_I_EN_CTL1 4
+#define Q_REG_I_MODE_CTL 0
+#define Q_REG_I_DIG_PULL_CTL 2
+#define Q_REG_I_DIG_IN_CTL 3
+#define Q_REG_I_DIG_VIN_CTL 4
+#define Q_REG_I_DIG_OUT_CTL 5
+#define Q_REG_I_EN_CTL 6
-/* control register configuration */
-#define Q_REG_VIN_SHIFT 0
-#define Q_REG_VIN_MASK 0x7
-#define Q_REG_PULL_SHIFT 4
-#define Q_REG_PULL_MASK 0x70
-#define Q_REG_INPUT_EN_SHIFT 7
-#define Q_REG_INPUT_EN_MASK 0x80
-#define Q_REG_OUT_STRENGTH_SHIFT 0
-#define Q_REG_OUT_STRENGTH_MASK 0x3
-#define Q_REG_OUT_TYPE_SHIFT 6
-#define Q_REG_OUT_TYPE_MASK 0x40
+/* control reg: mode */
#define Q_REG_OUT_INVERT_SHIFT 0
#define Q_REG_OUT_INVERT_MASK 0x1
#define Q_REG_SRC_SEL_SHIFT 1
#define Q_REG_SRC_SEL_MASK 0xE
-#define Q_REG_OUTPUT_EN_SHIFT 7
-#define Q_REG_OUTPUT_EN_MASK 0x80
+#define Q_REG_MODE_SEL_SHIFT 4
+#define Q_REG_MODE_SEL_MASK 0x70
+
+/* control reg: dig_vin */
+#define Q_REG_VIN_SHIFT 0
+#define Q_REG_VIN_MASK 0x7
+
+/* control reg: dig_pull */
+#define Q_REG_PULL_SHIFT 0
+#define Q_REG_PULL_MASK 0x7
+
+/* control reg: dig_out */
+#define Q_REG_OUT_STRENGTH_SHIFT 0
+#define Q_REG_OUT_STRENGTH_MASK 0x3
+#define Q_REG_OUT_TYPE_SHIFT 4
+#define Q_REG_OUT_TYPE_MASK 0x30
+
+/* control reg: en */
#define Q_REG_MASTER_EN_SHIFT 7
#define Q_REG_MASTER_EN_MASK 0x80
+/* param error checking */
+#define QPNP_GPIO_DIR_INVALID 3
+#define QPNP_GPIO_INVERT_INVALID 2
+#define QPNP_GPIO_OUT_BUF_INVALID 3
+#define QPNP_GPIO_VIN_INVALID 8
+#define QPNP_GPIO_PULL_INVALID 6
+#define QPNP_GPIO_OUT_STRENGTH_INVALID 4
+#define QPNP_GPIO_SRC_INVALID 8
+#define QPNP_GPIO_MASTER_INVALID 2
struct qpnp_gpio_spec {
uint8_t slave; /* 0-15 */
uint16_t offset; /* 0-255 */
uint32_t gpio_chip_idx; /* offset from gpio_chip base */
+ uint32_t pmic_gpio; /* PMIC gpio number */
int irq; /* logical IRQ number */
u8 regs[Q_NUM_CTL_REGS]; /* Control regs */
+ u8 type; /* peripheral type */
+ u8 subtype; /* peripheral subtype */
};
struct qpnp_gpio_chip {
@@ -121,6 +154,110 @@
q_chip->chip_gpios[chip_gpio] = spec;
}
+static int qpnp_gpio_check_config(struct qpnp_gpio_spec *q_spec,
+ struct qpnp_gpio_cfg *param)
+{
+ int gpio = q_spec->pmic_gpio;
+
+ if (param->direction >= QPNP_GPIO_DIR_INVALID)
+ pr_err("invalid direction for gpio %d\n", gpio);
+ else if (param->invert >= QPNP_GPIO_INVERT_INVALID)
+ pr_err("invalid invert polarity for gpio %d\n", gpio);
+ else if (param->src_select >= QPNP_GPIO_SRC_INVALID)
+ pr_err("invalid source select for gpio %d\n", gpio);
+ else if (param->out_strength >= QPNP_GPIO_OUT_STRENGTH_INVALID ||
+ param->out_strength == 0)
+ pr_err("invalid out strength for gpio %d\n", gpio);
+ else if (param->output_type >= QPNP_GPIO_OUT_BUF_INVALID)
+ pr_err("invalid out type for gpio %d\n", gpio);
+ else if ((param->output_type == QPNP_GPIO_OUT_BUF_OPEN_DRAIN_NMOS ||
+ param->output_type == QPNP_GPIO_OUT_BUF_OPEN_DRAIN_PMOS) &&
+ (q_spec->subtype == Q_GPIO_SUBTYPE_GPIOC_4CH ||
+ (q_spec->subtype == Q_GPIO_SUBTYPE_GPIOC_8CH)))
+ pr_err("invalid out type for gpio %d\n"
+ "gpioc does not support open-drain\n", gpio);
+ else if (param->vin_sel >= QPNP_GPIO_VIN_INVALID)
+ pr_err("invalid vin select value for gpio %d\n", gpio);
+ else if (param->pull >= QPNP_GPIO_PULL_INVALID)
+ pr_err("invalid pull value for gpio %d\n", gpio);
+ else if (param->master_en >= QPNP_GPIO_MASTER_INVALID)
+ pr_err("invalid master_en value for gpio %d\n", gpio);
+ else
+ return 0;
+
+ return -EINVAL;
+}
+
+static inline void q_reg_set(u8 *reg, int shift, int mask, int value)
+{
+ *reg |= (value << shift) & mask;
+}
+
+static inline void q_reg_clr_set(u8 *reg, int shift, int mask, int value)
+{
+ *reg &= ~mask;
+ *reg |= (value << shift) & mask;
+}
+
+static int _qpnp_gpio_config(struct qpnp_gpio_chip *q_chip,
+ struct qpnp_gpio_spec *q_spec,
+ struct qpnp_gpio_cfg *param)
+{
+ struct device *dev = &q_chip->spmi->dev;
+ int rc;
+
+ rc = qpnp_gpio_check_config(q_spec, param);
+ if (rc)
+ goto gpio_cfg;
+
+ /* set direction */
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
+ Q_REG_MODE_SEL_SHIFT, Q_REG_MODE_SEL_MASK,
+ param->direction);
+
+ /* output specific configuration */
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
+ Q_REG_OUT_INVERT_SHIFT, Q_REG_OUT_INVERT_MASK,
+ param->invert);
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
+ Q_REG_SRC_SEL_SHIFT, Q_REG_SRC_SEL_MASK,
+ param->src_select);
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_OUT_CTL],
+ Q_REG_OUT_STRENGTH_SHIFT, Q_REG_OUT_STRENGTH_MASK,
+ param->out_strength);
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_OUT_CTL],
+ Q_REG_OUT_TYPE_SHIFT, Q_REG_OUT_TYPE_MASK,
+ param->output_type);
+
+ /* config applicable for both input / output */
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_VIN_CTL],
+ Q_REG_VIN_SHIFT, Q_REG_VIN_MASK,
+ param->vin_sel);
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_DIG_PULL_CTL],
+ Q_REG_PULL_SHIFT, Q_REG_PULL_MASK,
+ param->pull);
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_EN_CTL],
+ Q_REG_MASTER_EN_SHIFT, Q_REG_MASTER_EN_MASK,
+ param->master_en);
+
+ rc = spmi_ext_register_writel(q_chip->spmi->ctrl, q_spec->slave,
+ Q_REG_ADDR(q_spec, Q_REG_MODE_CTL),
+ &q_spec->regs[Q_REG_I_MODE_CTL], Q_NUM_CTL_REGS);
+ if (rc) {
+ dev_err(&q_chip->spmi->dev, "%s: unable to write master"
+ " enable\n", __func__);
+ goto gpio_cfg;
+ }
+
+ return 0;
+
+gpio_cfg:
+ dev_err(dev, "%s: unable to set default config for"
+ " pmic gpio %d\n", __func__, q_spec->pmic_gpio);
+
+ return rc;
+}
+
int qpnp_gpio_config(int gpio, struct qpnp_gpio_cfg *param)
{
int rc, chip_offset;
@@ -146,47 +283,8 @@
}
}
mutex_unlock(&qpnp_gpio_chips_lock);
- if (!q_spec) {
- pr_err("gpio %d not handled by any pmic\n", gpio);
- return -EINVAL;
- }
- q_spec->regs[Q_REG_I_IO_CTL1] = (param->vin_sel <<
- Q_REG_VIN_SHIFT) & Q_REG_VIN_MASK;
- q_spec->regs[Q_REG_I_IO_CTL1] |= (param->pull <<
- Q_REG_PULL_SHIFT) & Q_REG_PULL_MASK;
- q_spec->regs[Q_REG_I_INPUT_CTL1] = ((param->direction &
- QPNP_GPIO_DIR_IN) ? ((1 << Q_REG_INPUT_EN_SHIFT)) : 0);
-
- if (param->direction & QPNP_GPIO_DIR_OUT) {
- q_spec->regs[Q_REG_I_OUTPUT_CTL1] = (param->out_strength
- << Q_REG_OUT_STRENGTH_SHIFT) & Q_REG_OUT_STRENGTH_MASK;
- q_spec->regs[Q_REG_I_OUTPUT_CTL1] |= (param->output_type
- << Q_REG_OUT_TYPE_SHIFT) & Q_REG_OUT_TYPE_MASK;
- } else {
- q_spec->regs[Q_REG_I_OUTPUT_CTL1] = 0;
- }
-
- if (param->direction & QPNP_GPIO_DIR_OUT) {
- q_spec->regs[Q_REG_I_OUTPUT_CTL2] = (param->output_value
- << Q_REG_OUT_INVERT_SHIFT) & Q_REG_OUT_INVERT_MASK;
- q_spec->regs[Q_REG_I_OUTPUT_CTL2] |= (param->src_select
- << Q_REG_SRC_SEL_SHIFT) & Q_REG_SRC_SEL_MASK;
- q_spec->regs[Q_REG_I_OUTPUT_CTL2] |= (1 <<
- Q_REG_OUTPUT_EN_SHIFT) & Q_REG_OUTPUT_EN_MASK;
- } else {
- q_spec->regs[Q_REG_I_OUTPUT_CTL2] = 0;
- }
-
- q_spec->regs[Q_REG_I_EN_CTL1] = (param->master_en <<
- Q_REG_MASTER_EN_SHIFT) & Q_REG_MASTER_EN_MASK;
-
- rc = spmi_ext_register_writel(q_chip->spmi->ctrl, q_spec->slave,
- Q_REG_ADDR(q_spec, Q_REG_IO_CTL1),
- &q_spec->regs[Q_REG_I_IO_CTL1], Q_NUM_CTL_REGS);
- if (rc)
- dev_err(&q_chip->spmi->dev, "%s: unable to write master"
- " enable\n", __func__);
+ rc = _qpnp_gpio_config(q_chip, q_spec, param);
return rc;
}
@@ -242,7 +340,8 @@
return -ENODEV;
/* gpio val is from RT status iff input is enabled */
- if (q_spec->regs[Q_REG_I_INPUT_CTL1] & Q_REG_INPUT_EN_MASK) {
+ if ((q_spec->regs[Q_REG_I_MODE_CTL] & Q_REG_MODE_SEL_MASK)
+ == QPNP_GPIO_DIR_IN) {
/* INT_RT_STS */
rc = spmi_ext_register_readl(q_chip->spmi->ctrl, q_spec->slave,
Q_REG_ADDR(q_spec, Q_REG_STATUS1),
@@ -250,7 +349,7 @@
return buf[0];
} else {
- ret_val = (q_spec->regs[Q_REG_I_OUTPUT_CTL2] &
+ ret_val = (q_spec->regs[Q_REG_I_MODE_CTL] &
Q_REG_OUT_INVERT_MASK) >> Q_REG_OUT_INVERT_SHIFT;
return ret_val;
}
@@ -266,15 +365,16 @@
if (!q_chip || !q_spec)
return -EINVAL;
- q_spec->regs[Q_REG_I_OUTPUT_CTL2] &= ~(1 << Q_REG_OUT_INVERT_SHIFT);
-
if (value)
- q_spec->regs[Q_REG_I_OUTPUT_CTL2] |=
- (1 << Q_REG_OUT_INVERT_SHIFT);
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
+ Q_REG_OUT_INVERT_SHIFT, Q_REG_OUT_INVERT_MASK, 1);
+ else
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
+ Q_REG_OUT_INVERT_SHIFT, Q_REG_OUT_INVERT_MASK, 0);
rc = spmi_ext_register_writel(q_chip->spmi->ctrl, q_spec->slave,
- Q_REG_ADDR(q_spec, Q_REG_OUTPUT_CTL2),
- &q_spec->regs[Q_REG_I_OUTPUT_CTL2], 1);
+ Q_REG_ADDR(q_spec, Q_REG_I_MODE_CTL),
+ &q_spec->regs[Q_REG_I_MODE_CTL], 1);
if (rc)
dev_err(&q_chip->spmi->dev, "%s: spmi write failed\n",
__func__);
@@ -306,21 +406,19 @@
if (!q_chip || !q_spec)
return -EINVAL;
- if (direction & QPNP_GPIO_DIR_IN) {
- q_spec->regs[Q_REG_I_INPUT_CTL1] |=
- (1 << Q_REG_INPUT_EN_SHIFT);
- q_spec->regs[Q_REG_I_OUTPUT_CTL2] &=
- ~(1 << Q_REG_OUTPUT_EN_SHIFT);
- } else {
- q_spec->regs[Q_REG_I_INPUT_CTL1] &=
- ~(1 << Q_REG_INPUT_EN_SHIFT);
- q_spec->regs[Q_REG_I_OUTPUT_CTL2] |=
- (1 << Q_REG_OUTPUT_EN_SHIFT);
+ if (direction >= QPNP_GPIO_DIR_INVALID) {
+ pr_err("invalid direction specification %d\n", direction);
+ return -EINVAL;
}
+ q_reg_clr_set(&q_spec->regs[Q_REG_I_MODE_CTL],
+ Q_REG_MODE_SEL_SHIFT,
+ Q_REG_MODE_SEL_MASK,
+ direction);
+
rc = spmi_ext_register_writel(q_chip->spmi->ctrl, q_spec->slave,
- Q_REG_ADDR(q_spec, Q_REG_INPUT_CTL1),
- &q_spec->regs[Q_REG_I_INPUT_CTL1], 3);
+ Q_REG_ADDR(q_spec, Q_REG_I_MODE_CTL),
+ &q_spec->regs[Q_REG_I_MODE_CTL], 1);
return rc;
}
@@ -374,14 +472,13 @@
u32 n = be32_to_cpup(gpio);
if (WARN_ON(gpio_chip->of_gpio_n_cells < 2)) {
- pr_err("%s: of_gpio_n_cells < 2\n", __func__);
+ pr_err("of_gpio_n_cells < 2\n");
return -EINVAL;
}
q_spec = qpnp_pmic_gpio_get_spec(q_chip, n);
if (!q_spec) {
- pr_err("%s: no such PMIC gpio %u in device topology\n",
- __func__, n);
+ pr_err("no such PMIC gpio %u in device topology\n", n);
return -EINVAL;
}
@@ -406,7 +503,7 @@
param.direction = be32_to_cpup(&prop[0]);
param.output_type = be32_to_cpup(&prop[1]);
- param.output_value = be32_to_cpup(&prop[2]);
+ param.invert = be32_to_cpup(&prop[2]);
param.pull = be32_to_cpup(&prop[3]);
param.vin_sel = be32_to_cpup(&prop[4]);
param.out_strength = be32_to_cpup(&prop[5]);
@@ -451,6 +548,7 @@
int i, rc, ret, gpio, len;
int lowest_gpio = INT_MAX, highest_gpio = INT_MIN;
u32 intspec[3];
+ char buf[2];
q_chip = kzalloc(sizeof(*q_chip), GFP_KERNEL);
if (!q_chip) {
@@ -562,6 +660,18 @@
q_spec->slave = spmi->sid;
q_spec->offset = res->start;
q_spec->gpio_chip_idx = i;
+ q_spec->pmic_gpio = gpio;
+
+ rc = spmi_ext_register_readl(spmi->ctrl, q_spec->slave,
+ Q_REG_ADDR(q_spec, Q_REG_TYPE), &buf[0], 2);
+ if (rc) {
+ dev_err(&spmi->dev, "%s: unable to read type regs\n",
+ __func__);
+ ret = rc;
+ goto err_probe;
+ }
+ q_spec->type = buf[0];
+ q_spec->subtype = buf[1];
/* call into irq_domain to get irq mapping */
intspec[0] = q_chip->spmi->sid;
@@ -628,15 +738,15 @@
/* initialize with hardware defaults */
rc = spmi_ext_register_readl(
q_chip->spmi->ctrl, q_spec->slave,
- Q_REG_ADDR(q_spec, Q_REG_IO_CTL1),
- &q_spec->regs[Q_REG_I_IO_CTL1],
+ Q_REG_ADDR(q_spec, Q_REG_EN_CTL),
+ &q_spec->regs[Q_REG_I_EN_CTL],
Q_NUM_CTL_REGS);
- q_spec->regs[Q_REG_I_EN_CTL1] |=
+ q_spec->regs[Q_REG_I_EN_CTL] |=
(1 << Q_REG_MASTER_EN_SHIFT);
rc = spmi_ext_register_writel(
q_chip->spmi->ctrl, q_spec->slave,
- Q_REG_ADDR(q_spec, Q_REG_EN_CTL1),
- &q_spec->regs[Q_REG_EN_CTL1], 1);
+ Q_REG_ADDR(q_spec, Q_REG_EN_CTL),
+ &q_spec->regs[Q_REG_I_EN_CTL], 1);
if (rc) {
dev_err(&spmi->dev, "%s: spmi write"
" failed\n", __func__);
diff --git a/include/linux/qpnp/gpio.h b/include/linux/qpnp/gpio.h
index a31b7f37..e7fb53e 100644
--- a/include/linux/qpnp/gpio.h
+++ b/include/linux/qpnp/gpio.h
@@ -12,12 +12,16 @@
#include <mach/qpnp.h>
+#define QPNP_GPIO_DIR_IN 0
#define QPNP_GPIO_DIR_OUT 1
-#define QPNP_GPIO_DIR_IN 2
-#define QPNP_GPIO_DIR_BOTH (QPNP_GPIO_DIR_OUT | QPNP_GPIO_DIR_IN)
+#define QPNP_GPIO_DIR_BOTH 2
-#define QPNP_GPIO_OUT_BUF_OPEN_DRAIN 1
+#define QPNP_GPIO_INVERT_DISABLE 0
+#define QPNP_GPIO_INVERT_ENABLE 1
+
#define QPNP_GPIO_OUT_BUF_CMOS 0
+#define QPNP_GPIO_OUT_BUF_OPEN_DRAIN_NMOS 1
+#define QPNP_GPIO_OUT_BUF_OPEN_DRAIN_PMOS 2
#define QPNP_GPIO_VIN0 0
#define QPNP_GPIO_VIN1 1
@@ -39,14 +43,17 @@
#define QPNP_GPIO_OUT_STRENGTH_MED 2
#define QPNP_GPIO_OUT_STRENGTH_HIGH 3
-#define QPNP_GPIO_FUNC_NORMAL 0
-#define QPNP_GPIO_FUNC_PAIRED 1
-#define QPNP_GPIO_FUNC_1 2
-#define QPNP_GPIO_FUNC_2 3
-#define QPNP_GPIO_DTEST1 4
-#define QPNP_GPIO_DTEST2 5
-#define QPNP_GPIO_DTEST3 6
-#define QPNP_GPIO_DTEST4 7
+#define QPNP_GPIO_SRC_FUNC_NORMAL 0
+#define QPNP_GPIO_SRC_FUNC_PAIRED 1
+#define QPNP_GPIO_SRC_FUNC_1 2
+#define QPNP_GPIO_SRC_FUNC_2 3
+#define QPNP_GPIO_SRC_DTEST1 4
+#define QPNP_GPIO_SRC_DTEST2 5
+#define QPNP_GPIO_SRC_DTEST3 6
+#define QPNP_GPIO_SRC_DTEST4 7
+
+#define QPNP_GPIO_MASTER_DISABLE 0
+#define QPNP_GPIO_MASTER_ENABLE 1
/**
* struct qpnp_gpio_cfg - structure to specify gpio configurtion values
@@ -54,7 +61,8 @@
* both. Should be of the type QPNP_GPIO_DIR_*
* @output_type: indicates gpio should be configured as CMOS or open
* drain. Should be of the type QPNP_GPIO_OUT_BUF_*
- * @output_value: The gpio output value of the gpio line - 0 or 1
+ * @invert: Invert the signal of the gpio line -
+ * QPNP_GPIO_INVERT_DISABLE or QPNP_GPIO_INVERT_ENABLE
* @pull: Indicates whether a pull up or pull down should be
* applied. If a pullup is required the current strength
* needs to be specified. Current values of 30uA, 1.5uA,
@@ -68,21 +76,22 @@
* @source_sel: choose alternate function for the gpio. Certain gpios
* can be paired (shorted) with each other. Some gpio pin
* can act as alternate functions. This parameter should
- * be of type QPNP_GPIO_FUNC_*
- * @master_en: 1 = Enable features within the GPIO block based on
- * configurations.
- * 0 = Completely disable the GPIO block and let the pin
- * float with high impedance regardless of other settings.
+ * be of type QPNP_GPIO_SRC_*.
+ * @master_en: QPNP_GPIO_MASTER_ENABLE = Enable features within the
+ * GPIO block based on configurations.
+ * QPNP_GPIO_MASTER_DISABLE = Completely disable the GPIO
+ * block and let the pin float with high impedance
+ * regardless of other settings.
*/
struct qpnp_gpio_cfg {
- int direction;
- int output_type;
- int output_value;
- int pull;
- int vin_sel;
- int out_strength;
- int src_select;
- int master_en;
+ unsigned int direction;
+ unsigned int output_type;
+ unsigned int invert;
+ unsigned int pull;
+ unsigned int vin_sel;
+ unsigned int out_strength;
+ unsigned int src_select;
+ unsigned int master_en;
};
/**