Merge change I5fa471ae
* changes:
[msm7630]: Add code to support qwerty keypad in lk bootloader
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 665c566..dbfc0ac 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -2,31 +2,32 @@
* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
+ * Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Code Aurora nor
+ * the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
*/
#include <app.h>
@@ -328,10 +329,8 @@
{
page_size = flash_page_size();
page_mask = page_size - 1;
-#ifndef PLATFORM_MSM7X30
if (keys_get_state(KEY_BACK) != 0)
goto fastboot;
-#endif
boot_linux_from_flash();
dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
diff --git a/dev/keys/gpio_keypad.c b/dev/keys/gpio_keypad.c
index 5d15076..bb95f77 100644
--- a/dev/keys/gpio_keypad.c
+++ b/dev/keys/gpio_keypad.c
@@ -2,6 +2,8 @@
* Copyright (c) 2009, Google Inc.
* All rights reserved.
*
+ * Copyright (c) 2009, 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:
@@ -38,6 +40,7 @@
#include <dev/gpio_keypad.h>
#include <kernel/event.h>
#include <kernel/timer.h>
+#include <reg.h>
struct gpio_kp {
struct gpio_keypad_info *keypad_info;
@@ -48,6 +51,16 @@
unsigned long keys_pressed[0];
};
+struct gpio_qwerty_kp {
+ struct qwerty_keypad_info *keypad_info;
+ struct timer timer;
+ event_t full_scan;
+ int num_of_scans;
+ unsigned int some_keys_pressed:2;
+ unsigned long keys_pressed[0];
+};
+
+static struct gpio_qwerty_kp *qwerty_keypad;
/* TODO: Support multiple keypads? */
static struct gpio_kp *keypad;
@@ -176,3 +189,293 @@
/* wait for the keypad to complete one full scan */
event_wait(&keypad->full_scan);
}
+
+int i2c_ssbi_poll_for_device_ready(void)
+{
+ unsigned long timeout = SSBI_TIMEOUT_US;
+
+ while (!(readl(MSM_SSBI_BASE + SSBI2_STATUS) & SSBI_STATUS_READY)) {
+ if (--timeout == 0) {
+ dprintf(INFO, "In Device ready function:Timeout, status %x\n", readl(MSM_SSBI_BASE + SSBI2_STATUS));
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int i2c_ssbi_poll_for_read_completed(void)
+{
+ unsigned long timeout = SSBI_TIMEOUT_US;
+
+ while (!(readl(MSM_SSBI_BASE + SSBI2_STATUS) & SSBI_STATUS_RD_READY)) {
+ if (--timeout == 0) {
+ dprintf(INFO, "In read completed function:Timeout, status %x\n", readl(MSM_SSBI_BASE + SSBI2_STATUS));
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int i2c_ssbi_read_bytes(unsigned char *buffer, unsigned short length,
+ unsigned short slave_addr)
+{
+ int ret = 0;
+ unsigned char *buf = buffer;
+ unsigned short len = length;
+ unsigned short addr = slave_addr;
+ unsigned long read_cmd = SSBI_CMD_READ(addr);
+ unsigned long mode2 = readl(MSM_SSBI_BASE + SSBI2_MODE2);
+
+ //buf = alloc(len * sizeof(8));
+ if (mode2 & SSBI_MODE2_SSBI2_MODE)
+ writel(SSBI_MODE2_REG_ADDR_15_8(mode2, addr),
+ MSM_SSBI_BASE + SSBI2_MODE2);
+
+ while (len) {
+ ret = i2c_ssbi_poll_for_device_ready();
+ if (ret) {
+ dprintf (CRITICAL, "Error: device not ready\n");
+ return ret;
+ }
+
+ writel(read_cmd, MSM_SSBI_BASE + SSBI2_CMD);
+
+ ret = i2c_ssbi_poll_for_read_completed();
+ if (ret) {
+ dprintf (CRITICAL, "Error: read not completed\n");
+ return ret;
+ }
+
+ *buf++ = readl(MSM_SSBI_BASE + SSBI2_RD) & SSBI_RD_REG_DATA_MASK;
+ len--;
+ }
+ return 0;
+}
+
+int i2c_ssbi_write_bytes(unsigned char *buffer, unsigned short length,
+ unsigned short slave_addr)
+{
+ int ret = 0;
+ unsigned long timeout = SSBI_TIMEOUT_US;
+ unsigned char *buf = buffer;
+ unsigned short len = length;
+ unsigned short addr = slave_addr;
+ unsigned long mode2 = readl(MSM_SSBI_BASE + SSBI2_MODE2);
+
+ if (mode2 & SSBI_MODE2_SSBI2_MODE)
+ writel(SSBI_MODE2_REG_ADDR_15_8(mode2, addr),
+ MSM_SSBI_BASE + SSBI2_MODE2);
+
+ while (len) {
+ ret = i2c_ssbi_poll_for_device_ready();
+ if (ret) {
+ dprintf (CRITICAL, "Error: device not ready\n");
+ return ret;
+ }
+
+ writel(SSBI_CMD_WRITE(addr, *buf++), MSM_SSBI_BASE + SSBI2_CMD);
+
+ while (readl(MSM_SSBI_BASE + SSBI2_STATUS) & SSBI_STATUS_MCHN_BUSY) {
+ if (--timeout == 0) {
+ dprintf(INFO, "In Device ready function:Timeout, status %x\n", readl(MSM_SSBI_BASE + SSBI2_STATUS));
+ return 1;
+ }
+ }
+ len--;
+ }
+ return 0;
+}
+
+int pm8058_gpio_config(int gpio, struct pm8058_gpio *param)
+{
+ int rc;
+ unsigned char bank[8];
+ static int dir_map[] = {
+ PM8058_GPIO_MODE_OFF,
+ PM8058_GPIO_MODE_OUTPUT,
+ PM8058_GPIO_MODE_INPUT,
+ PM8058_GPIO_MODE_BOTH,
+ };
+
+ if (param == 0) {
+ dprintf (INFO, "pm8058_gpio struct not defined\n");
+ return -1;
+ }
+
+ /* Select banks and configure the gpio */
+ bank[0] = PM8058_GPIO_WRITE |
+ ((param->vin_sel << PM8058_GPIO_VIN_SHIFT) &
+ PM8058_GPIO_VIN_MASK) |
+ PM8058_GPIO_MODE_ENABLE;
+ bank[1] = PM8058_GPIO_WRITE |
+ ((1 << PM8058_GPIO_BANK_SHIFT) & PM8058_GPIO_BANK_MASK) |
+ ((dir_map[param->direction] << PM8058_GPIO_MODE_SHIFT) &
+ PM8058_GPIO_MODE_MASK) |
+ ((param->direction & PM_GPIO_DIR_OUT) ?
+ PM8058_GPIO_OUT_BUFFER : 0);
+ bank[2] = PM8058_GPIO_WRITE |
+ ((2 << PM8058_GPIO_BANK_SHIFT) & PM8058_GPIO_BANK_MASK) |
+ ((param->pull << PM8058_GPIO_PULL_SHIFT) &
+ PM8058_GPIO_PULL_MASK);
+ bank[3] = PM8058_GPIO_WRITE |
+ ((3 << PM8058_GPIO_BANK_SHIFT) & PM8058_GPIO_BANK_MASK) |
+ ((param->out_strength << PM8058_GPIO_OUT_STRENGTH_SHIFT) &
+ PM8058_GPIO_OUT_STRENGTH_MASK);
+ bank[4] = PM8058_GPIO_WRITE |
+ ((4 << PM8058_GPIO_BANK_SHIFT) & PM8058_GPIO_BANK_MASK) |
+ ((param->function << PM8058_GPIO_FUNC_SHIFT) &
+ PM8058_GPIO_FUNC_MASK);
+
+ rc = i2c_ssbi_write_bytes(bank, 5, SSBI_REG_ADDR_GPIO(gpio));
+ if (rc) {
+ dprintf(INFO, "Failed on 1st ssbi_write(): rc=%d.\n", rc);
+ return 1;
+ }
+ return 0;
+}
+
+int pm8058_gpio_config_kypd_drv(int gpio_start, int num_gpios)
+{
+ int rc;
+ struct pm8058_gpio kypd_drv = {
+ .direction = PM_GPIO_DIR_OUT,
+ .pull = PM_GPIO_PULL_NO,
+ .vin_sel = 2,
+ .out_strength = PM_GPIO_STRENGTH_LOW,
+ .function = PM_GPIO_FUNC_1,
+ .inv_int_pol = 1,
+ };
+
+ while (num_gpios--) {
+ rc = pm8058_gpio_config(gpio_start++, &kypd_drv);
+ if (rc) {
+ dprintf(INFO, "FAIL pm8058_gpio_config(): rc=%d.\n", rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+int pm8058_gpio_config_kypd_sns(int gpio_start, int num_gpios)
+{
+ int rc;
+ struct pm8058_gpio kypd_sns = {
+ .direction = PM_GPIO_DIR_IN,
+ .pull = PM_GPIO_PULL_UP1,
+ .vin_sel = 2,
+ .out_strength = PM_GPIO_STRENGTH_NO,
+ .function = PM_GPIO_FUNC_NORMAL,
+ .inv_int_pol = 1,
+ };
+
+ while (num_gpios--) {
+ rc = pm8058_gpio_config(gpio_start++, &kypd_sns);
+ if (rc) {
+ dprintf(INFO, "FAIL pm8058_gpio_config(): rc=%d.\n", rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+static enum handler_return
+scan_qwerty_keypad(struct timer *timer, time_t now, void *arg)
+{
+ int rows = (qwerty_keypad->keypad_info)->rows;
+ int columns = (qwerty_keypad->keypad_info)->columns;
+ unsigned char column_keys = 0x00;
+ int shift = 0;
+ static int key_detected = 0;
+
+ if (i2c_ssbi_read_bytes((qwerty_keypad->keypad_info)->rec_keys, NUM_OF_SSBI_READS,
+ SSBI_REG_KYPD_REC_DATA_ADDR))
+ dprintf (CRITICAL, "Error in initializing SSBI_REG_KYPD_CNTL register\n");
+
+ if (i2c_ssbi_read_bytes((qwerty_keypad->keypad_info)->old_keys, NUM_OF_SSBI_READS,
+ SSBI_REG_KYPD_OLD_DATA_ADDR))
+ dprintf (CRITICAL, "Error in initializing SSBI_REG_KYPD_CNTL register\n");
+
+ while (rows--) {
+ if ((qwerty_keypad->keypad_info)->rec_keys[rows]
+ != (qwerty_keypad->keypad_info)->old_keys[rows]) {
+ while (columns--) {
+ column_keys = ((qwerty_keypad->keypad_info)->rec_keys[rows]);
+ if ((0x01 << columns) & (~column_keys)) {
+ shift = (rows * (qwerty_keypad->keypad_info)->columns) + columns;
+ if ((qwerty_keypad->keypad_info)->keymap[shift]) {
+ if (shift != key_detected) {
+ // key_changed((qwerty_keypad->keypad_info)->keymap[shift], 1);
+ key_detected = shift;
+ keys_post_event((qwerty_keypad->keypad_info)->keymap[shift], 1);
+ event_signal(&qwerty_keypad->full_scan, false);
+ timer_set_oneshot(timer, (qwerty_keypad->keypad_info)->poll_time,
+ scan_qwerty_keypad, NULL);
+ return INT_RESCHEDULE;
+
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (qwerty_keypad->num_of_scans < 10)
+ {
+ (qwerty_keypad->num_of_scans)++;
+ timer_set_oneshot(timer, (qwerty_keypad->keypad_info)->settle_time,
+ scan_qwerty_keypad, NULL);
+ return INT_RESCHEDULE;
+ }
+
+ event_signal(&qwerty_keypad->full_scan, false);
+ return INT_RESCHEDULE;
+
+}
+
+void ssbi_gpio_init(void)
+{
+ unsigned char kypd_cntl_init = 0xF8;
+ unsigned char kypd_scan_init = 0x20;
+
+ if (i2c_ssbi_write_bytes(&kypd_cntl_init, 1, SSBI_REG_KYPD_CNTL_ADDR))
+ dprintf (CRITICAL, "Error in initializing SSBI_REG_KYPD_CNTL register\n");
+
+ if (i2c_ssbi_write_bytes(&kypd_scan_init, 1, SSBI_REG_KYPD_SCAN_ADDR))
+ dprintf (CRITICAL, "Error in initializing SSBI_REG_KYPD_SCAN register\n");
+
+ pm8058_gpio_config_kypd_sns(SSBI_OFFSET_ADDR_GPIO_KYPD_SNS, NUM_OF_KYPD_SNS_GPIOS);
+ pm8058_gpio_config_kypd_drv(SSBI_OFFSET_ADDR_GPIO_KYPD_DRV, NUM_OF_KYPD_DRV_GPIOS);
+
+
+}
+
+void ssbi_keypad_init(struct qwerty_keypad_info *qwerty_kp)
+{
+ int *modem_stat_check = (SMEM_BASE + 0x14);
+ int len;
+
+ /* Wait for modem to be ready before keypad init */
+ while (readl(modem_stat_check) != 1);
+
+ ssbi_gpio_init();
+
+ len = sizeof(struct gpio_qwerty_kp);
+ qwerty_keypad = malloc(len);
+ ASSERT(qwerty_keypad);
+
+ memset(qwerty_keypad, 0, len);
+ qwerty_keypad->keypad_info = qwerty_kp;
+ qwerty_keypad->num_of_scans = 0;
+
+ event_init(&qwerty_keypad->full_scan, false, EVENT_FLAG_AUTOUNSIGNAL);
+ timer_initialize(&qwerty_keypad->timer);
+ timer_set_oneshot(&qwerty_keypad->timer, 0, scan_qwerty_keypad, NULL);
+
+ /* wait for the keypad to complete one full scan */
+ event_wait(&qwerty_keypad->full_scan);
+}
+
diff --git a/include/dev/gpio_keypad.h b/include/dev/gpio_keypad.h
index 3e05128..8c006d3 100644
--- a/include/dev/gpio_keypad.h
+++ b/include/dev/gpio_keypad.h
@@ -2,6 +2,8 @@
* Copyright (c) 2008, Google Inc.
* All rights reserved.
*
+ * Copyright (c) 2009, 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:
@@ -53,4 +55,156 @@
void gpio_keypad_init(struct gpio_keypad_info *kpinfo);
+//Macros for SSBI Qwerty keypad for 7x30
+
+/* SSBI 2.0 controller registers */
+#define MSM_SSBI_BASE 0xAD900000
+#define SMEM_BASE 0x100000
+
+#define SSBI_TIMEOUT_US 100
+
+#define SSBI2_CTL 0x0000
+#define SSBI2_RESET 0x0004
+#define SSBI2_CMD 0x0008
+#define SSBI2_RD 0x0010
+#define SSBI2_STATUS 0x0014
+#define SSBI2_PRIORITIES 0x0018
+#define SSBI2_MODE2 0x001C
+
+/* SSBI_CMD fields */
+#define SSBI_CMD_SEND_TERM_SYM (0x01 << 27)
+#define SSBI_CMD_WAKEUP_SLAVE (0x01 << 26)
+#define SSBI_CMD_USE_ENABLE (0x01 << 25)
+#define SSBI_CMD_RDWRN (0x01 << 24)
+#define SSBI_CMD_REG_ADDR_SHFT (0x10)
+#define SSBI_CMD_REG_ADDR_MASK (0xFF << SSBI_CMD_REG_ADDR_SHFT)
+#define SSBI_CMD_REG_DATA_SHFT (0x00)
+#define SSBI_CMD_REG_DATA_MASK (0xFF << SSBI_CMD_REG_DATA_SHFT)
+
+/* SSBI_STATUS fields */
+#define SSBI_STATUS_DATA_IN 0x10
+#define SSBI_STATUS_RD_CLOBBERED 0x08
+#define SSBI_STATUS_RD_READY 0x04
+#define SSBI_STATUS_READY 0x02
+#define SSBI_STATUS_MCHN_BUSY 0x01
+
+/* SSBI_RD fields */
+#define SSBI_RD_USE_ENABLE 0x02000000
+#define SSBI_RD_RDWRN 0x01000000
+#define SSBI_RD_REG_ADDR_SHFT 0x10
+#define SSBI_RD_REG_ADDR_MASK (0xFF << SSBI_RD_REG_ADDR_SHFT)
+#define SSBI_RD_REG_DATA_SHFT (0x00)
+#define SSBI_RD_REG_DATA_MASK (0xFF << SSBI_RD_REG_DATA_SHFT)
+
+/* SSBI_MODE2 fields */
+#define SSBI_MODE2_REG_ADDR_15_8_SHFT 0x04
+#define SSBI_MODE2_REG_ADDR_15_8_MASK (0x7F << SSBI_MODE2_REG_ADDR_15_8_SHFT)
+#define SSBI_MODE2_ADDR_WIDTH_SHFT 0x01
+#define SSBI_MODE2_ADDR_WIDTH_MASK (0x07 << SSBI_MODE2_ADDR_WIDTH_SHFT)
+#define SSBI_MODE2_SSBI2_MODE 0x00000001
+
+//Keypad controller configurations
+#define SSBI_REG_KYPD_CNTL_ADDR 0x148
+#define SSBI_REG_KYPD_SCAN_ADDR 0x149
+#define SSBI_REG_KYPD_TEST_ADDR 0x14A
+#define SSBI_REG_KYPD_REC_DATA_ADDR 0x14B
+#define SSBI_REG_KYPD_OLD_DATA_ADDR 0x14C
+
+// GPIO configurations
+
+#define SSBI_REG_ADDR_GPIO_BASE 0x150
+#define SSBI_OFFSET_ADDR_GPIO_KYPD_SNS 0x000
+#define SSBI_OFFSET_ADDR_GPIO_KYPD_DRV 0x008
+#define SSBI_REG_ADDR_GPIO(n) (SSBI_REG_ADDR_GPIO_BASE + n)
+
+#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
+
+#define PM8058_GPIO_BANK_MASK 0x70
+#define PM8058_GPIO_BANK_SHIFT 4
+#define PM8058_GPIO_WRITE 0x80
+
+/* Bank 0 */
+#define PM8058_GPIO_VIN_MASK 0x0E
+#define PM8058_GPIO_VIN_SHIFT 1
+#define PM8058_GPIO_MODE_ENABLE 0x01
+
+/* Bank 1 */
+#define PM8058_GPIO_MODE_MASK 0x0C
+#define PM8058_GPIO_MODE_SHIFT 2
+#define PM8058_GPIO_OUT_BUFFER 0x02
+#define PM8058_GPIO_OUT_INVERT 0x01
+
+#define PM8058_GPIO_MODE_OFF 3
+#define PM8058_GPIO_MODE_OUTPUT 2
+#define PM8058_GPIO_MODE_INPUT 0
+#define PM8058_GPIO_MODE_BOTH 1
+
+/* Bank 2 */
+#define PM8058_GPIO_PULL_MASK 0x0E
+#define PM8058_GPIO_PULL_SHIFT 1
+
+/* Bank 3 */
+#define PM8058_GPIO_OUT_STRENGTH_MASK 0x0C
+#define PM8058_GPIO_OUT_STRENGTH_SHIFT 2
+
+/* Bank 4 */
+#define PM8058_GPIO_FUNC_MASK 0x0E
+#define PM8058_GPIO_FUNC_SHIFT 1
+
+#define NUM_OF_SSBI_READS 15
+#define NUM_OF_KYPD_DRV_GPIOS 12
+#define NUM_OF_KYPD_SNS_GPIOS 8
+
+struct pm8058_gpio {
+ int direction;
+ int pull;
+ int vin_sel; /* 0..7 */
+ int out_strength;
+ int function;
+ int inv_int_pol; /* invert interrupt polarity */
+};
+
+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;
+ /* time to wait before reading inputs after driving each output */
+ time_t settle_time;
+ time_t poll_time;
+ unsigned flags;
+};
+
+#define SSBI_CMD_READ(AD) \
+ (SSBI_CMD_RDWRN | (((AD) & 0xFF) << SSBI_CMD_REG_ADDR_SHFT))
+
+#define SSBI_CMD_WRITE(AD, DT) \
+ ((((AD) & 0xFF) << SSBI_CMD_REG_ADDR_SHFT) | \
+ (((DT) & 0xFF) << SSBI_CMD_REG_DATA_SHFT))
+
+#define SSBI_MODE2_REG_ADDR_15_8(MD, AD) \
+ (((MD) & 0x0F) | ((((AD) >> 8) << SSBI_MODE2_REG_ADDR_15_8_SHFT) & \
+ SSBI_MODE2_REG_ADDR_15_8_MASK))
+
+void ssbi_keypad_init (struct qwerty_keypad_info *);
+
#endif /* __DEV_GPIO_KEYPAD_H */
diff --git a/target/msm7630_surf/init.c b/target/msm7630_surf/init.c
index 0f2d816..63dff0b 100644
--- a/target/msm7630_surf/init.c
+++ b/target/msm7630_surf/init.c
@@ -83,8 +83,8 @@
dprintf(INFO, "target_init()\n");
- //keys_init();
- //keypad_init();
+ keys_init();
+ keypad_init();
ptable_init(&flash_ptable);
smem_ptable_init();
diff --git a/target/msm7630_surf/keypad.c b/target/msm7630_surf/keypad.c
index c44b06d..4fa6913 100644
--- a/target/msm7630_surf/keypad.c
+++ b/target/msm7630_surf/keypad.c
@@ -34,79 +34,30 @@
#include <dev/gpio_keypad.h>
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
+#define BITS_IN_ELEMENT(x) (sizeof(x)[0] * 8)
-/* don't turn this on without updating the ffa support */
-#define SCAN_FUNCTION_KEYS 0
+static unsigned char qwerty_keys_old[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char qwerty_keys_new[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00};
-static unsigned int halibut_row_gpios[] = {
- 31, 32, 33, 34, 35, 41
-#if SCAN_FUNCTION_KEYS
- , 42
-#endif
+#define KEYMAP_INDEX(row, col) (row)* BITS_IN_ELEMENT(qwerty_keys_new) + (col)
+
+static unsigned int qwerty_keymap[] = {
+ [KEYMAP_INDEX(4, 2)] = KEY_BACK, /* -L on SURF & FFA */
};
-static unsigned int halibut_col_gpios[] = { 36, 37, 38, 39, 40 };
-
-#define KEYMAP_INDEX(row, col) ((row)*ARRAY_SIZE(halibut_col_gpios) + (col))
-
-static const unsigned short halibut_keymap[ARRAY_SIZE(halibut_col_gpios) * ARRAY_SIZE(halibut_row_gpios)] = {
- [KEYMAP_INDEX(0, 0)] = KEY_5,
- [KEYMAP_INDEX(0, 1)] = KEY_9,
- [KEYMAP_INDEX(0, 2)] = KEY_SOFT1,
- [KEYMAP_INDEX(0, 3)] = KEY_6,
- [KEYMAP_INDEX(0, 4)] = KEY_LEFT,
-
- [KEYMAP_INDEX(1, 0)] = KEY_0,
- [KEYMAP_INDEX(1, 1)] = KEY_RIGHT,
- [KEYMAP_INDEX(1, 2)] = KEY_1,
- [KEYMAP_INDEX(1, 3)] = KEY_SHARP,
- [KEYMAP_INDEX(1, 4)] = KEY_SEND,
-
- [KEYMAP_INDEX(2, 0)] = KEY_VOLUMEUP,
- [KEYMAP_INDEX(2, 1)] = KEY_HOME, /* FA */
- [KEYMAP_INDEX(2, 2)] = KEY_F8, /* QCHT */
- [KEYMAP_INDEX(2, 3)] = KEY_F6, /* R+ */
- [KEYMAP_INDEX(2, 4)] = KEY_F7, /* R- */
-
- [KEYMAP_INDEX(3, 0)] = KEY_UP,
- [KEYMAP_INDEX(3, 1)] = KEY_CLEAR,
- [KEYMAP_INDEX(3, 2)] = KEY_4,
- [KEYMAP_INDEX(3, 3)] = KEY_MUTE, /* SPKR */
- [KEYMAP_INDEX(3, 4)] = KEY_2,
-
- [KEYMAP_INDEX(4, 0)] = KEY_SOFT2, /* SOFT2 */
- [KEYMAP_INDEX(4, 1)] = KEY_CENTER, /* KEY_CENTER */
- [KEYMAP_INDEX(4, 2)] = KEY_DOWN,
- [KEYMAP_INDEX(4, 3)] = KEY_BACK, /* FB */
- [KEYMAP_INDEX(4, 4)] = KEY_8,
-
- [KEYMAP_INDEX(5, 0)] = KEY_VOLUMEDOWN,
- [KEYMAP_INDEX(5, 1)] = KEY_STAR, /* KEY_STAR */
- [KEYMAP_INDEX(5, 2)] = KEY_MAIL, /* MESG */
- [KEYMAP_INDEX(5, 3)] = KEY_3,
- [KEYMAP_INDEX(5, 4)] = KEY_7,
-
-#if SCAN_FUNCTION_KEYS
- [KEYMAP_INDEX(6, 0)] = KEY_F5,
- [KEYMAP_INDEX(6, 1)] = KEY_F4,
- [KEYMAP_INDEX(6, 2)] = KEY_F3,
- [KEYMAP_INDEX(6, 3)] = KEY_F2,
- [KEYMAP_INDEX(6, 4)] = KEY_F1
-#endif
-};
-
-static struct gpio_keypad_info halibut_keypad_info = {
- .keymap = halibut_keymap,
- .output_gpios = halibut_row_gpios,
- .input_gpios = halibut_col_gpios,
- .noutputs = ARRAY_SIZE(halibut_row_gpios),
- .ninputs = ARRAY_SIZE(halibut_col_gpios),
- .settle_time = 5 /* msec */,
- .poll_time = 20 /* msec */,
- .flags = GPIOKPF_DRIVE_INACTIVE,
+static struct qwerty_keypad_info qwerty_keypad = {
+ .keymap = qwerty_keymap,
+ .old_keys = qwerty_keys_old,
+ .rec_keys = qwerty_keys_new,
+ .rows = ARRAY_SIZE(qwerty_keys_new),
+ .columns = sizeof(unsigned char) * 8,
+ .settle_time = 5 /* msec */,
+ .poll_time = 20 /* msec */,
};
void keypad_init(void)
{
- gpio_keypad_init(&halibut_keypad_info);
+ ssbi_keypad_init(&qwerty_keypad);
}