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);