dev/pmic: adds pm8921 gpio config api
Change-Id: I995b23be5b45d75a518fc1f010aeeefba692124b
diff --git a/dev/pmic/pm8921/include/dev/pm8921.h b/dev/pmic/pm8921/include/dev/pm8921.h
index faca8e2..db95b71 100644
--- a/dev/pmic/pm8921/include/dev/pm8921.h
+++ b/dev/pmic/pm8921/include/dev/pm8921.h
@@ -31,6 +31,26 @@
#include <sys/types.h>
+
+#define PM_GPIO_DIR_OUT 0x01
+#define PM_GPIO_DIR_IN 0x02
+#define PM_GPIO_DIR_BOTH (PM_GPIO_DIR_OUT | PM_GPIO_DIR_IN)
+
+#define PM_GPIO_PULL_UP1 2
+#define PM_GPIO_PULL_UP2 3
+#define PM_GPIO_PULL_DN 4
+#define PM_GPIO_PULL_NO 5
+
+#define PM_GPIO_STRENGTH_NO 0
+#define PM_GPIO_STRENGTH_HIGH 1
+#define PM_GPIO_STRENGTH_MED 2
+#define PM_GPIO_STRENGTH_LOW 3
+
+#define PM_GPIO_FUNC_NORMAL 0
+#define PM_GPIO_FUNC_PAIRED 1
+#define PM_GPIO_FUNC_1 2
+#define PM_GPIO_FUNC_2 3
+
typedef struct
{
uint32_t initialized;
@@ -41,7 +61,20 @@
} pm8921_dev_t;
+struct pm8921_gpio {
+ int direction;
+ int output_buffer;
+ int output_value;
+ int pull;
+ int vin_sel;
+ int out_strength;
+ int function;
+ int inv_int_pol;
+ int disable_pin;
+};
+
void pm8921_init(pm8921_dev_t *);
+int pm8921_gpio_config(int gpio, struct pm8921_gpio *param);
void pm8921_boot_done(void);
#endif
diff --git a/dev/pmic/pm8921/pm8921.c b/dev/pmic/pm8921/pm8921.c
index 6a47e05..bc7e7d4 100644
--- a/dev/pmic/pm8921/pm8921.c
+++ b/dev/pmic/pm8921/pm8921.c
@@ -65,3 +65,75 @@
val |= (SYS_CONFIG_2_BOOT_DONE | SYS_CONFIG_2_ADAPTIVE_BOOT_DISABLE);
dev->write(&val, 1, SYS_CONFIG_2);
}
+
+/* Configure PMIC GPIO */
+int pm8921_gpio_config(int gpio, struct pm8921_gpio *param)
+{
+ int ret;
+ uint8_t bank[6];
+ uint8_t output_buf_config;
+ uint8_t output_value;
+
+ static uint8_t dir_map[] = {
+ PM_GPIO_MODE_OFF,
+ PM_GPIO_MODE_OUTPUT,
+ PM_GPIO_MODE_INPUT,
+ PM_GPIO_MODE_BOTH,
+ };
+
+ if (param == NULL) {
+ dprintf (INFO, "pm8291_gpio struct not defined\n");
+ return -1;
+ }
+
+ /* Select banks and configure the gpio */
+ bank[0] = PM_GPIO_WRITE |
+ ((param->vin_sel << PM_GPIO_VIN_SHIFT) &
+ PM_GPIO_VIN_MASK) |
+ PM_GPIO_MODE_ENABLE;
+
+ /* bank1 */
+ if ((param->direction & PM_GPIO_DIR_OUT) && param->output_buffer)
+ output_buf_config = PM_GPIO_OUT_BUFFER_OPEN_DRAIN;
+ else
+ output_buf_config = 0;
+
+ if ((param->direction & PM_GPIO_DIR_OUT) && param->output_value)
+ output_value = 1;
+ else
+ output_value = 0;
+
+ bank[1] = PM_GPIO_WRITE |
+ ((1 << PM_GPIO_BANK_SHIFT) & PM_GPIO_BANK_MASK) |
+ ((dir_map[param->direction] << PM_GPIO_MODE_SHIFT)
+ & PM_GPIO_MODE_MASK) |
+ output_buf_config |
+ output_value;
+
+ bank[2] = PM_GPIO_WRITE |
+ ((2 << PM_GPIO_BANK_SHIFT) & PM_GPIO_BANK_MASK) |
+ ((param->pull << PM_GPIO_PULL_SHIFT) &
+ PM_GPIO_PULL_MASK);
+
+ bank[3] = PM_GPIO_WRITE |
+ ((3 << PM_GPIO_BANK_SHIFT) & PM_GPIO_BANK_MASK) |
+ ((param->out_strength << PM_GPIO_OUT_STRENGTH_SHIFT) &
+ PM_GPIO_OUT_STRENGTH_MASK) |
+ (param->disable_pin ? PM_GPIO_PIN_DISABLE : PM_GPIO_PIN_ENABLE);
+
+ bank[4] = PM_GPIO_WRITE |
+ ((4 << PM_GPIO_BANK_SHIFT) & PM_GPIO_BANK_MASK) |
+ ((param->function << PM_GPIO_FUNC_SHIFT) &
+ PM_GPIO_FUNC_MASK);
+
+ bank[5] = PM_GPIO_WRITE |
+ ((5 << PM_GPIO_BANK_SHIFT) & PM_GPIO_BANK_MASK) |
+ (param->inv_int_pol ? 0 : PM_GPIO_NON_INT_POL_INV);
+
+ ret = dev->write(bank, 6, GPIO_CNTL(gpio));
+ if (ret) {
+ dprintf(INFO, "Failed to write to PM8921 ret=%d.\n", ret);
+ return -1;
+ }
+ return 0;
+}
diff --git a/dev/pmic/pm8921/pm8921_hw.h b/dev/pmic/pm8921/pm8921_hw.h
index 49069ee..1fba8f2 100644
--- a/dev/pmic/pm8921/pm8921_hw.h
+++ b/dev/pmic/pm8921/pm8921_hw.h
@@ -27,9 +27,51 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define PBL_ACCESS_2 0x005
-#define PBL_ACCESS_2_ENUM_TIMER_STOP (1 << 1)
+#define PBL_ACCESS_2 0x005
+#define PBL_ACCESS_2_ENUM_TIMER_STOP (1 << 1)
-#define SYS_CONFIG_2 0x007
-#define SYS_CONFIG_2_BOOT_DONE (1 << 6)
-#define SYS_CONFIG_2_ADAPTIVE_BOOT_DISABLE (1 << 7)
+#define SYS_CONFIG_2 0x007
+#define SYS_CONFIG_2_BOOT_DONE (1 << 6)
+#define SYS_CONFIG_2_ADAPTIVE_BOOT_DISABLE (1 << 7)
+
+#define GPIO_CNTL_BASE 0x150
+#define GPIO_CNTL(n) (GPIO_CNTL_BASE + n)
+
+/* GPIO Bank register programming */
+#define PM_GPIO_BANK_MASK 0x70
+#define PM_GPIO_BANK_SHIFT 4
+#define PM_GPIO_WRITE 0x80
+
+/* Bank 0 */
+#define PM_GPIO_VIN_MASK 0x0E
+#define PM_GPIO_VIN_SHIFT 1
+#define PM_GPIO_MODE_ENABLE 0x01
+
+/* Bank 1 */
+#define PM_GPIO_MODE_MASK 0x0C
+#define PM_GPIO_MODE_SHIFT 2
+#define PM_GPIO_OUT_BUFFER_OPEN_DRAIN 0x02
+#define PM_GPIO_OUT_INVERT 0x01
+
+#define PM_GPIO_MODE_OFF 3
+#define PM_GPIO_MODE_OUTPUT 2
+#define PM_GPIO_MODE_INPUT 0
+#define PM_GPIO_MODE_BOTH 1
+
+/* Bank 2 */
+#define PM_GPIO_PULL_MASK 0x0E
+#define PM_GPIO_PULL_SHIFT 1
+
+/* Bank 3 */
+#define PM_GPIO_OUT_STRENGTH_MASK 0x0C
+#define PM_GPIO_OUT_STRENGTH_SHIFT 2
+#define PM_GPIO_PIN_ENABLE 0x00
+#define PM_GPIO_PIN_DISABLE 0x01
+
+/* Bank 4 */
+#define PM_GPIO_FUNC_MASK 0x0E
+#define PM_GPIO_FUNC_SHIFT 1
+
+/* Bank 5 */
+#define PM_GPIO_NON_INT_POL_INV 0x08
+