dev: pmic: add pmi gpio and lpg support
Add slave id as an extra parameter so that configuration
of both PM and PMI's gpio and lpg channel are supported.
Change-Id: I7dbd7838601fd5cb4aa144fe9c4b74129e74a665
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index 2471d0a..9315f72 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -156,6 +156,85 @@
return 0;
}
+/* Configure PM and PMI GPIO with slave id */
+int pm8x41_gpio_config_sid(uint8_t sid, uint8_t gpio, struct pm8x41_gpio *config)
+{
+ uint8_t val;
+ uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio);
+
+ gpio_base &= 0x0ffff; /* clear sid */
+ gpio_base |= (sid << 16); /* add sid */
+
+ dprintf(SPEW, "%s: gpio=%d base=%x\n", __func__, gpio, gpio_base);
+
+ /* Disable the GPIO */
+ val = REG_READ(gpio_base + GPIO_EN_CTL);
+ val &= ~BIT(PERPH_EN_BIT);
+ REG_WRITE(gpio_base + GPIO_EN_CTL, val);
+
+ /* Select the mode */
+ val = config->function | (config->direction << 4);
+ REG_WRITE(gpio_base + GPIO_MODE_CTL, val);
+
+ /* Set the right pull */
+ val = config->pull;
+ REG_WRITE(gpio_base + GPIO_DIG_PULL_CTL, val);
+
+ /* Select the VIN */
+ val = config->vin_sel;
+ REG_WRITE(gpio_base + GPIO_DIG_VIN_CTL, val);
+
+ if (config->direction == PM_GPIO_DIR_OUT) {
+ /* Set the right dig out control */
+ val = config->out_strength | (config->output_buffer << 4);
+ REG_WRITE(gpio_base + GPIO_DIG_OUT_CTL, val);
+ }
+
+ /* Enable the GPIO */
+ val = REG_READ(gpio_base + GPIO_EN_CTL);
+ val |= BIT(PERPH_EN_BIT);
+ REG_WRITE(gpio_base + GPIO_EN_CTL, val);
+
+ return 0;
+}
+
+/* Reads the status of requested gpio */
+int pm8x41_gpio_get_sid(uint8_t sid, uint8_t gpio, uint8_t *status)
+{
+ uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio);
+
+ gpio_base &= 0x0ffff; /* clear sid */
+ gpio_base |= (sid << 16); /* add sid */
+
+ *status = REG_READ(gpio_base + GPIO_STATUS);
+
+ /* Return the value of the GPIO pin */
+ *status &= BIT(GPIO_STATUS_VAL_BIT);
+
+ dprintf(SPEW, "GPIO %d status is %d\n", gpio, *status);
+
+ return 0;
+}
+
+/* Write the output value of the requested gpio */
+int pm8x41_gpio_set_sid(uint8_t sid, uint8_t gpio, uint8_t value)
+{
+ uint32_t gpio_base = GPIO_N_PERIPHERAL_BASE(gpio);
+ uint8_t val;
+
+ gpio_base &= 0x0ffff; /* clear sid */
+ gpio_base |= (sid << 16); /* add sid */
+
+ dprintf(SPEW, "%s: gpio=%d base=%x\n", __func__, gpio, gpio_base);
+
+ /* Set the output value of the gpio */
+ val = REG_READ(gpio_base + GPIO_MODE_CTL);
+ val = (val & ~PM_GPIO_OUTPUT_MASK) | value;
+ REG_WRITE(gpio_base + GPIO_MODE_CTL, val);
+
+ return 0;
+}
+
/* Prepare PON RESIN S2 reset (bite) */
void pm8x41_resin_s2_reset_enable()
{
@@ -377,6 +456,21 @@
REG_WRITE(lpg_base + off, val);
}
+/*
+ * pmi lpg channel register write with slave_id:
+ */
+void pm8x41_lpg_write_sid(uint8_t sid, uint8_t chan, uint8_t off, uint8_t val)
+{
+ uint32_t lpg_base = LPG_N_PERIPHERAL_BASE(chan);
+
+ lpg_base &= 0x0ffff; /* clear sid */
+ lpg_base |= (sid << 16); /* add sid */
+
+ dprintf(SPEW, "%s: lpg=%d base=%x\n", __func__, chan, lpg_base);
+
+ REG_WRITE(lpg_base + off, val);
+}
+
uint8_t pm8x41_get_pmic_rev()
{
return REG_READ(REVID_REVISION4);