/*
 * Copyright (c) 2011-2012, The Linux Foundation. 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 The Linux Foundation 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 <string.h>
#include <debug.h>
#include <dev/keys.h>
#include <dev/ssbi.h>
#include <dev/gpio_keypad.h>
#include <dev/pm8921.h>
#include <platform/gpio.h>
#include <sys/types.h>
#include <board.h>
#include <smem.h>

#define BITS_IN_ELEMENT(x) (sizeof(x) * 8)
#define KEYMAP_INDEX(row, col) (row)* BITS_IN_ELEMENT(unsigned int) + (col)

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 */
};

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 */ ,
};

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 */
};

unsigned int msm8930_keys_pm8038_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 */
};

unsigned int msm8930_keys_pm8917_gpiomap[] = {
	[KEYMAP_INDEX(0, 0)] = PM_GPIO(27),	/* Volume key on the device/CDP */
	[KEYMAP_INDEX(0, 1)] = PM_GPIO(28),	/* Volume key on the device/CDP */
};

struct qwerty_keypad_info msm8930_pm8038_qwerty_keypad = {
	.keymap = msm8930_qwerty_keymap,
	.gpiomap = msm8930_keys_pm8038_gpiomap,
	.mapsize = ARRAY_SIZE(msm8930_qwerty_keymap),
	.key_gpio_get = &pm8921_gpio_get,
	.settle_time = 5 /* msec */ ,
	.poll_time = 20 /* msec */ ,
};

struct qwerty_keypad_info msm8930_pm8917_qwerty_keypad = {
	.keymap = msm8930_qwerty_keymap,
	.gpiomap = msm8930_keys_pm8917_gpiomap,
	.mapsize = ARRAY_SIZE(msm8930_qwerty_keymap),
	.key_gpio_get = &pm8921_gpio_get,
	.settle_time = 5 /* msec */ ,
	.poll_time = 20 /* msec */ ,
};

unsigned int apq8064_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 */
};

unsigned int apq8064_pm8921_keys_gpiomap[] = {
	[KEYMAP_INDEX(0, 0)] = PM_GPIO(35),	/* Volume key on the device/CDP */
	[KEYMAP_INDEX(0, 1)] = PM_GPIO(38),	/* Volume key on the device/CDP */
};

unsigned int apq8064_pm8917_keys_gpiomap[] = {
	[KEYMAP_INDEX(0, 0)] = PM_GPIO(35),	/* Volume key on the device/CDP */
	[KEYMAP_INDEX(0, 1)] = PM_GPIO(30),	/* Volume key on the device/CDP */
};

struct qwerty_keypad_info apq8064_pm8921_qwerty_keypad = {
	.keymap = apq8064_qwerty_keymap,
	.gpiomap = apq8064_pm8921_keys_gpiomap,
	.mapsize = ARRAY_SIZE(apq8064_qwerty_keymap),
	.key_gpio_get = &pm8921_gpio_get,
	.settle_time = 5 /* msec */ ,
	.poll_time = 20 /* msec */ ,
};

struct qwerty_keypad_info apq8064_pm8917_qwerty_keypad = {
	.keymap = apq8064_qwerty_keymap,
	.gpiomap = apq8064_pm8917_keys_gpiomap,
	.mapsize = ARRAY_SIZE(apq8064_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();

	if (platform_pmic_type(PMIC_IS_PM8917))
	{
		ssbi_gpio_keypad_init(&msm8930_pm8917_qwerty_keypad);
	}
	else
	{
		ssbi_gpio_keypad_init(&msm8930_pm8038_qwerty_keypad);
	}
}

void apq8064_keypad_init(void)
{
	apq8064_keypad_gpio_init();

	if (platform_pmic_type(PMIC_IS_PM8917))
		ssbi_gpio_keypad_init(&apq8064_pm8917_qwerty_keypad);
	else
		ssbi_gpio_keypad_init(&apq8064_pm8921_qwerty_keypad);
}

/* Configure keypad_drv through pwm or DBUS inputs or manually */
int led_kp_set( int current,
	enum kp_backlight_mode mode,
	enum kp_backlight_flash_logic flash_logic)
{
	int rc = pm8921_config_drv_keypad(current, flash_logic, mode);

	if (rc)
	{
		dprintf(CRITICAL, "FAIL pm8921_config_drv_keypad(): rc=%d.\n", rc);
	}
}

/* Configure gpio 26 through lpg2 */
void keypad_led_drv_on_pwm(void)
{
	struct pm8921_gpio keypad_pwm = {
		.direction = PM_GPIO_DIR_OUT,
		.output_buffer = 0,
		.output_value = 0,
		.pull = PM_GPIO_PULL_NO,
		.vin_sel = 2,
		.out_strength = PM_GPIO_STRENGTH_HIGH,
		.function = PM_GPIO_FUNC_2,
		.inv_int_pol = 0,
	};

	int rc = pm8921_gpio_config(PM_GPIO(26), &keypad_pwm);
	if (rc)
	{
	dprintf(CRITICAL, "FAIL pm8921_gpio_config(): rc=%d.\n", rc);
	}
}
