msm8960: msm8930: Enable PMIC GPIO based keypad.

Change-Id: Ic23ace4b6c04332d7601944af6cf3ed5ffc53e1b
diff --git a/dev/keys/gpio_keypad.c b/dev/keys/gpio_keypad.c
index f7a8673..efe0a02 100644
--- a/dev/keys/gpio_keypad.c
+++ b/dev/keys/gpio_keypad.c
@@ -2,7 +2,7 @@
  * Copyright (c) 2009, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -437,6 +437,58 @@
     event_wait(&qwerty_keypad->full_scan);
 }
 
+static enum handler_return
+scan_qwerty_gpio_keypad(struct timer *timer, time_t now, void *arg)
+{
+	int i=0;
+	int num =0;
+	uint8_t key_status;
+	struct qwerty_keypad_info *keypad = qwerty_keypad->keypad_info;
+
+	num = keypad->mapsize;
+
+	for(i=0; i < num; i++)
+	{
+		/*continue if not interested in key*/
+		if(!keypad->keymap[i])
+			continue;
+
+		/*read key gpio*/
+		keypad->key_gpio_get(keypad->gpiomap[i], &key_status);
+
+		/*Post event if key pressed*/
+		if(key_status)
+		{
+			keys_post_event(keypad->keymap[i], 1);
+			goto done;
+		}
+	}
+
+done:
+	event_signal(&qwerty_keypad->full_scan, false);
+	return INT_RESCHEDULE;
+}
+
+void ssbi_gpio_keypad_init(struct qwerty_keypad_info  *qwerty_kp)
+{
+	int len;
+
+	len = sizeof(struct gpio_qwerty_kp);
+	qwerty_keypad = malloc(len);
+	ASSERT(qwerty_keypad);
+
+	memset(qwerty_keypad, 0, len);
+	qwerty_keypad->keypad_info = qwerty_kp;
+
+	event_init(&qwerty_keypad->full_scan, false, EVENT_FLAG_AUTOUNSIGNAL);
+	timer_initialize(&qwerty_keypad->timer);
+
+	timer_set_oneshot(&qwerty_keypad->timer, 0, scan_qwerty_gpio_keypad, NULL);
+
+	/* wait for the keypad to complete one full scan */
+	event_wait(&qwerty_keypad->full_scan);
+}
+
 void pmic_write(unsigned address, unsigned data)
 {
   write_func wr_function = &i2c_ssbi_write_bytes;
diff --git a/dev/pmic/pm8921/include/dev/pm8921.h b/dev/pmic/pm8921/include/dev/pm8921.h
index e2c185b..bff76e9 100644
--- a/dev/pmic/pm8921/include/dev/pm8921.h
+++ b/dev/pmic/pm8921/include/dev/pm8921.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -37,6 +37,7 @@
 #define PM_GPIO_DIR_BOTH        (PM_GPIO_DIR_OUT | PM_GPIO_DIR_IN)
 
 #define PM_GPIO_PULL_UP_30      0
+#define PM_GPIO_PULL_UP_1_5     1
 #define PM_GPIO_PULL_UP_31_5    2
 /* 1.5uA + 30uA boost */
 #define PM_GPIO_PULL_UP_1_5_30  3
diff --git a/include/dev/gpio_keypad.h b/include/dev/gpio_keypad.h
index 77348f6..c536e24 100644
--- a/include/dev/gpio_keypad.h
+++ b/include/dev/gpio_keypad.h
@@ -2,7 +2,7 @@
  * Copyright (c) 2008, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -131,17 +131,21 @@
 
 typedef int (*read_func)(unsigned char *, unsigned short, unsigned short);
 typedef int (*write_func)(unsigned char *, unsigned short, unsigned short);
+typedef int (*gpio_get_func)(uint8_t, uint8_t *);
 
 struct qwerty_keypad_info {
-	/* size must be ninputs * noutputs */
 	unsigned int   *keymap;
-        unsigned char  *old_keys;
-        unsigned char  *rec_keys;
-        unsigned int   rows;
-        unsigned int   columns;
-        unsigned int   num_of_reads;
-        read_func      rd_func;
-        write_func     wr_func;
+	unsigned int   *gpiomap;
+	unsigned int   mapsize;
+	unsigned char  *old_keys;
+	unsigned char  *rec_keys;
+	unsigned int   rows;
+	unsigned int   columns;
+	unsigned int   num_of_reads;
+	read_func      rd_func;
+	write_func     wr_func;
+	gpio_get_func  key_gpio_get;
+
 	/* time to wait before reading inputs after driving each output */
 	time_t         settle_time;
 	time_t         poll_time;
diff --git a/platform/msm8960/gpio.c b/platform/msm8960/gpio.c
index 638ad8c..52db863 100644
--- a/platform/msm8960/gpio.c
+++ b/platform/msm8960/gpio.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -31,6 +31,8 @@
 #include <platform/iomap.h>
 #include <platform/gpio.h>
 #include <gsbi.h>
+#include <dev/pm8921.h>
+#include <sys/types.h>
 
 void gpio_tlmm_config(uint32_t gpio, uint8_t func,
 		      uint8_t dir, uint8_t pull,
@@ -80,3 +82,85 @@
 		ASSERT(0);
 	}
 }
+
+struct pm8xxx_gpio_init {
+	uint32_t gpio;
+	struct pm8921_gpio config;
+};
+
+#define PM8XXX_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
+			_func, _inv, _disable) \
+{ \
+	.gpio	= _gpio, \
+	.config	= { \
+		.direction	= _dir, \
+		.output_buffer	= _buf, \
+		.output_value	= _val, \
+		.pull		= _pull, \
+		.vin_sel	= _vin, \
+		.out_strength	= _out_strength, \
+		.function	= _func, \
+		.inv_int_pol	= _inv, \
+		.disable_pin	= _disable, \
+	} \
+}
+
+#define PM8XXX_GPIO_OUTPUT(_gpio, _val) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, 0, _val, \
+			PM_GPIO_PULL_NO, 2, \
+			PM_GPIO_STRENGTH_HIGH, \
+			PM_GPIO_FUNC_NORMAL, 1, 0)
+
+
+#define PM8XXX_GPIO_INPUT(_gpio, _pull) \
+	PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, \
+			_pull, 2, \
+			PM_GPIO_STRENGTH_NO, \
+			PM_GPIO_FUNC_NORMAL, 1, 0)
+
+/* Initial pm8038 GPIO configurations */
+static struct pm8xxx_gpio_init pm8038_keypad_gpios[] = {
+	/* keys GPIOs */
+	PM8XXX_GPIO_INPUT(PM_GPIO(3), PM_GPIO_PULL_UP_1_5),
+	PM8XXX_GPIO_INPUT(PM_GPIO(8), PM_GPIO_PULL_UP_1_5),
+	PM8XXX_GPIO_INPUT(PM_GPIO(10), PM_GPIO_PULL_UP_1_5),
+	PM8XXX_GPIO_INPUT(PM_GPIO(11), PM_GPIO_PULL_UP_1_5),
+};
+
+static struct pm8xxx_gpio_init pm8921_keypad_gpios[] = {
+	/* keys GPIOs */
+	PM8XXX_GPIO_INPUT(PM_GPIO(1), PM_GPIO_PULL_UP_31_5),
+	PM8XXX_GPIO_INPUT(PM_GPIO(2), PM_GPIO_PULL_UP_31_5),
+	PM8XXX_GPIO_INPUT(PM_GPIO(3), PM_GPIO_PULL_UP_31_5),
+	PM8XXX_GPIO_INPUT(PM_GPIO(4), PM_GPIO_PULL_UP_31_5),
+	PM8XXX_GPIO_INPUT(PM_GPIO(5), PM_GPIO_PULL_UP_31_5),
+	PM8XXX_GPIO_OUTPUT(PM_GPIO(9), 0),
+};
+
+void msm8960_keypad_gpio_init()
+{
+		int i = 0;
+		int num = 0;
+
+		num = ARRAY_SIZE(pm8921_keypad_gpios);
+
+		for(i=0; i < num; i++)
+		{
+			pm8921_gpio_config(pm8921_keypad_gpios[i].gpio,
+								&(pm8921_keypad_gpios[i].config));
+		}
+}
+
+void msm8930_keypad_gpio_init()
+{
+		int i = 0;
+		int num = 0;
+
+		num = ARRAY_SIZE(pm8038_keypad_gpios);
+
+		for(i=0; i < num; i++)
+		{
+			pm8921_gpio_config(pm8038_keypad_gpios[i].gpio,
+								&(pm8038_keypad_gpios[i].config));
+		}
+}
diff --git a/platform/msm8960/include/platform/gpio.h b/platform/msm8960/include/platform/gpio.h
index 178fde2..62bf0d7 100644
--- a/platform/msm8960/include/platform/gpio.h
+++ b/platform/msm8960/include/platform/gpio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -55,5 +55,7 @@
 
 void gpio_config_i2c(uint8_t gsbi_id);
 void gpio_config_uart_dm(uint8_t id);
+void msm8960_keypad_gpio_init();
+void msm8930_keypad_gpio_init();
 
 #endif
diff --git a/target/msm8960/init.c b/target/msm8960/init.c
index 8dee5ff..d6afcec 100644
--- a/target/msm8960/init.c
+++ b/target/msm8960/init.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2009, Google Inc.
  * All rights reserved.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -68,7 +68,8 @@
 #define LINUX_MACHTYPE_8064_RUMI3   3679
 
 extern void dmb(void);
-extern void keypad_init(void);
+extern void msm8960_keypad_init(void);
+extern void msm8930_keypad_init(void);
 extern void panel_backlight_on(void);
 
 static unsigned mmc_sdc_base[] =
@@ -118,7 +119,15 @@
 
 	/* Keypad init */
 	keys_init();
-	keypad_init();
+
+	if(platform_id == MSM8960)
+	{
+		msm8960_keypad_init();
+	}
+	else if(platform_id == MSM8930)
+	{
+		msm8930_keypad_init();
+	}
 
 	/* Display splash screen if enabled */
 #if DISPLAY_SPLASH_SCREEN
diff --git a/target/msm8960/keypad.c b/target/msm8960/keypad.c
index 806f07f..8bbd005 100644
--- a/target/msm8960/keypad.c
+++ b/target/msm8960/keypad.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -33,42 +33,60 @@
 #include <dev/ssbi.h>
 #include <dev/gpio_keypad.h>
 #include <dev/pm8921.h>
+#include <platform/gpio.h>
+#include <sys/types.h>
 
+#define BITS_IN_ELEMENT(x) (sizeof(x) * 8)
+#define KEYMAP_INDEX(row, col) (row)* BITS_IN_ELEMENT(unsigned int) + (col)
 
-#define NUM_OF_ROWS 1
-#define NUM_OF_COLS 5
-
-#define BITS_IN_ELEMENT(x) (sizeof(x)[0] * 8)
-
-static unsigned char qwerty_keys_old[NUM_OF_ROWS];
-static unsigned char qwerty_keys_new[NUM_OF_ROWS];
-
-#define KEYMAP_INDEX(row, col) (row)* BITS_IN_ELEMENT(qwerty_keys_new) + (col)
-
-unsigned int qwerty_keymap[] = {
+unsigned int msm8960_qwerty_keymap[] = {
 	[KEYMAP_INDEX(0, 0)] = KEY_VOLUMEUP,	/* Volume key on the device/CDP */
 	[KEYMAP_INDEX(0, 1)] = KEY_VOLUMEDOWN,	/* Volume key on the device/CDP */
 };
 
-struct qwerty_keypad_info qwerty_keypad = {
-	.keymap = qwerty_keymap,
-	.old_keys = qwerty_keys_old,
-	.rec_keys = qwerty_keys_new,
-	.rows = NUM_OF_ROWS,
-	.columns = NUM_OF_COLS,
-	.num_of_reads = NUM_OF_ROWS,
-	.rd_func = &pa1_ssbi2_read_bytes,
-	.wr_func = &pa1_ssbi2_write_bytes,
+unsigned int msm8960_keys_gpiomap[] = {
+	[KEYMAP_INDEX(0, 0)] = PM_GPIO(1),	/* Volume key on the device/CDP */
+	[KEYMAP_INDEX(0, 1)] = PM_GPIO(2),	/* Volume key on the device/CDP */
+};
+
+struct qwerty_keypad_info msm8960_qwerty_keypad = {
+	.keymap = msm8960_qwerty_keymap,
+	.gpiomap = msm8960_keys_gpiomap,
+	.mapsize = ARRAY_SIZE(msm8960_qwerty_keymap),
+	.key_gpio_get = &pm8921_gpio_get,
 	.settle_time = 5 /* msec */ ,
 	.poll_time = 20 /* msec */ ,
 };
 
-void keypad_init(void)
-{
-	memset(qwerty_keys_old, 0, sizeof(qwerty_keys_old));
-	memset(qwerty_keys_new, 0, sizeof(qwerty_keys_new));
+unsigned int msm8930_qwerty_keymap[] = {
+	[KEYMAP_INDEX(0, 0)] = KEY_VOLUMEUP,	/* Volume key on the device/CDP */
+	[KEYMAP_INDEX(0, 1)] = KEY_VOLUMEDOWN,	/* Volume key on the device/CDP */
+};
 
-	ssbi_keypad_init(&qwerty_keypad);
+unsigned int msm8930_keys_gpiomap[] = {
+	[KEYMAP_INDEX(0, 0)] = PM_GPIO(3),	/* Volume key on the device/CDP */
+	[KEYMAP_INDEX(0, 1)] = PM_GPIO(8),	/* Volume key on the device/CDP */
+};
+
+struct qwerty_keypad_info msm8930_qwerty_keypad = {
+	.keymap = msm8930_qwerty_keymap,
+	.gpiomap = msm8930_keys_gpiomap,
+	.mapsize = ARRAY_SIZE(msm8930_qwerty_keymap),
+	.key_gpio_get = &pm8921_gpio_get,
+	.settle_time = 5 /* msec */ ,
+	.poll_time = 20 /* msec */ ,
+};
+
+void msm8960_keypad_init(void)
+{
+	msm8960_keypad_gpio_init();
+	ssbi_gpio_keypad_init(&msm8960_qwerty_keypad);
+}
+
+void msm8930_keypad_init(void)
+{
+	msm8930_keypad_gpio_init();
+	ssbi_gpio_keypad_init(&msm8930_qwerty_keypad);
 }
 
 /* Configure keypad_drv through pwm or DBUS inputs or manually */