/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/slab.h>
#include <linux/err.h>
#include <asm/mach-types.h>
#include <mach/board.h>
#include <mach/rpc_pmapp.h>
#include <mach/msm_rpcrouter.h>
#include <mach/vreg.h>

#define PMAPP_RPC_PROG			0x30000060
#define PMAPP_RPC_VER_1_1		0x00010001
#define PMAPP_RPC_VER_1_2		0x00010002
#define PMAPP_RPC_VER_2_1		0x00020001
#define PMAPP_RPC_VER_3_1		0x00030001
#define PMAPP_RPC_VER_5_1		0x00050001
#define PMAPP_RPC_VER_6_1		0x00060001
#define PMAPP_RPC_VER_7_1		0x00070001

#define VBUS_SESS_VALID_CB_PROC			1
#define PM_VOTE_USB_PWR_SEL_SWITCH_APP__HSUSB 	(1 << 2)
#define PM_USB_PWR_SEL_SWITCH_ID 		0

#define PMAPP_RPC_TIMEOUT (5*HZ)

#define PMAPP_DISPLAY_CLOCK_CONFIG_PROC		21
#define PMAPP_VREG_LEVEL_VOTE_PROC		23
#define PMAPP_SMPS_CLOCK_VOTE_PROC		26
#define PMAPP_CLOCK_VOTE_PROC			27
#define PMAPP_SMPS_MODE_VOTE_PROC		28
#define PMAPP_VREG_PINCNTRL_VOTE_PROC		30
#define PMAPP_DISP_BACKLIGHT_SET_PROC		31
#define PMAPP_DISP_BACKLIGHT_INIT_PROC		32
#define PMAPP_VREG_LPM_PINCNTRL_VOTE_PROC	34

/* Clock voter name max length */
#define PMAPP_CLOCK_VOTER_ID_LEN		4

struct rpc_pmapp_ids {
	unsigned long	reg_for_vbus_valid;
	unsigned long	vote_for_vbus_valid_switch;
};

static struct rpc_pmapp_ids rpc_ids;
static struct msm_rpc_client *client;

/* Add newer versions at the top of array */
static const unsigned int rpc_vers[] = {
	PMAPP_RPC_VER_7_1,
	PMAPP_RPC_VER_6_1,
	PMAPP_RPC_VER_5_1,
	PMAPP_RPC_VER_3_1,
	PMAPP_RPC_VER_2_1,
};

static void rpc_pmapp_init_rpc_ids(unsigned long vers)
{
	if (vers == PMAPP_RPC_VER_1_1) {
		rpc_ids.reg_for_vbus_valid		= 5;
		rpc_ids.vote_for_vbus_valid_switch	= 6;
	} else if (vers == PMAPP_RPC_VER_1_2) {
		rpc_ids.reg_for_vbus_valid		= 16;
		rpc_ids.vote_for_vbus_valid_switch	= 17;
	} else if (vers == PMAPP_RPC_VER_2_1) {
		rpc_ids.reg_for_vbus_valid		= 0; /* NA */
		rpc_ids.vote_for_vbus_valid_switch	= 0; /* NA */
	}
}

struct usb_pwr_sel_switch_args {
	uint32_t cmd;
	uint32_t switch_id;
	uint32_t app_mask;
};

static int usb_pwr_sel_switch_arg_cb(struct msm_rpc_client *client,
					void *buf, void *data)
{
	struct usb_pwr_sel_switch_args *args = buf;

	args->cmd = cpu_to_be32(*(uint32_t *)data);
	args->switch_id = cpu_to_be32(PM_USB_PWR_SEL_SWITCH_ID);
	args->app_mask = cpu_to_be32(PM_VOTE_USB_PWR_SEL_SWITCH_APP__HSUSB);
	return sizeof(struct usb_pwr_sel_switch_args);
}

static int msm_pm_app_vote_usb_pwr_sel_switch(uint32_t cmd)
{
	return msm_rpc_client_req(client,
			rpc_ids.vote_for_vbus_valid_switch,
			usb_pwr_sel_switch_arg_cb,
			&cmd, NULL, NULL, -1);
}

struct vbus_sess_valid_args {
	uint32_t cb_id;
};

static int vbus_sess_valid_arg_cb(struct msm_rpc_client *client,
					void *buf, void *data)
{
	struct vbus_sess_valid_args *args = buf;

	args->cb_id = cpu_to_be32(*(uint32_t *)data);
	return sizeof(struct vbus_sess_valid_args);
}


int pmic_vote_3p3_pwr_sel_switch(int boost)
{
	int ret;

	ret = msm_pm_app_vote_usb_pwr_sel_switch(boost);

	return ret;
}
EXPORT_SYMBOL(pmic_vote_3p3_pwr_sel_switch);

struct vbus_sn_notification_args {
	uint32_t cb_id;
	uint32_t vbus; /* vbus = 0 if VBUS is present */
};

static int vbus_notification_cb(struct msm_rpc_client *client,
				void *buffer, int in_size)
{
	struct vbus_sn_notification_args *args;
	struct rpc_request_hdr *req = buffer;
	int rc;
	uint32_t accept_status;
	void (*cb_func)(int);
	uint32_t cb_id;
	int vbus;

	args = (struct vbus_sn_notification_args *) (req + 1);
	cb_id = be32_to_cpu(args->cb_id);
	vbus = be32_to_cpu(args->vbus);

	cb_func = msm_rpc_get_cb_func(client, cb_id);
	if (cb_func) {
		cb_func(!vbus);
		accept_status = RPC_ACCEPTSTAT_SUCCESS;
	} else
		accept_status = RPC_ACCEPTSTAT_SYSTEM_ERR;

	msm_rpc_start_accepted_reply(client, be32_to_cpu(req->xid),
				     accept_status);
	rc = msm_rpc_send_accepted_reply(client, 0);
	if (rc)
		pr_err("%s: send accepted reply failed: %d\n", __func__, rc);

	return rc;
}

static int pm_app_usb_cb_func(struct msm_rpc_client *client,
				void *buffer, int in_size)
{
	int rc;
	struct rpc_request_hdr *req = buffer;

	switch (be32_to_cpu(req->procedure)) {
	case VBUS_SESS_VALID_CB_PROC:
		rc = vbus_notification_cb(client, buffer, in_size);
		break;
	default:
		pr_err("%s: procedure not supported %d\n", __func__,
		       be32_to_cpu(req->procedure));
		msm_rpc_start_accepted_reply(client, be32_to_cpu(req->xid),
					     RPC_ACCEPTSTAT_PROC_UNAVAIL);
		rc = msm_rpc_send_accepted_reply(client, 0);
		if (rc)
			pr_err("%s: sending reply failed: %d\n", __func__, rc);
		break;
	}
	return rc;
}

int msm_pm_app_rpc_init(void (*callback)(int online))
{
	uint32_t cb_id, rc;

	if (!machine_is_qsd8x50_ffa() && !machine_is_msm7x27_ffa())
		return -ENOTSUPP;

	client = msm_rpc_register_client("pmapp_usb",
			PMAPP_RPC_PROG,
			PMAPP_RPC_VER_2_1, 1,
			pm_app_usb_cb_func);
	if (!IS_ERR(client)) {
		rpc_pmapp_init_rpc_ids(PMAPP_RPC_VER_2_1);
		goto done;
	}

	client = msm_rpc_register_client("pmapp_usb",
			PMAPP_RPC_PROG,
			PMAPP_RPC_VER_1_2, 1,
			pm_app_usb_cb_func);
	if (!IS_ERR(client)) {
		rpc_pmapp_init_rpc_ids(PMAPP_RPC_VER_1_2);
		goto done;
	}

	client = msm_rpc_register_client("pmapp_usb",
			PMAPP_RPC_PROG,
			PMAPP_RPC_VER_1_1, 1,
			pm_app_usb_cb_func);
	if (!IS_ERR(client))
		rpc_pmapp_init_rpc_ids(PMAPP_RPC_VER_1_1);
	else
		return PTR_ERR(client);

done:
	cb_id = msm_rpc_add_cb_func(client, (void *)callback);
	/* In case of NULL callback funtion, cb_id would be -1 */
	if ((int) cb_id < -1)
		return cb_id;
	rc =  msm_rpc_client_req(client,
		rpc_ids.reg_for_vbus_valid,
			vbus_sess_valid_arg_cb,
				&cb_id, NULL, NULL, -1);
	return rc;
}
EXPORT_SYMBOL(msm_pm_app_rpc_init);

void msm_pm_app_rpc_deinit(void(*callback)(int online))
{
	if (client) {
		msm_rpc_remove_cb_func(client, (void *)callback);
		msm_rpc_unregister_client(client);
	}
}
EXPORT_SYMBOL(msm_pm_app_rpc_deinit);

/* error bit flags defined by modem side */
#define PM_ERR_FLAG__PAR1_OUT_OF_RANGE		(0x0001)
#define PM_ERR_FLAG__PAR2_OUT_OF_RANGE		(0x0002)
#define PM_ERR_FLAG__PAR3_OUT_OF_RANGE		(0x0004)
#define PM_ERR_FLAG__PAR4_OUT_OF_RANGE		(0x0008)
#define PM_ERR_FLAG__PAR5_OUT_OF_RANGE		(0x0010)

#define PM_ERR_FLAG__ALL_PARMS_OUT_OF_RANGE   	(0x001F) /* all 5 previous */

#define PM_ERR_FLAG__SBI_OPT_ERR		(0x0080)
#define PM_ERR_FLAG__FEATURE_NOT_SUPPORTED	(0x0100)

#define	PMAPP_BUFF_SIZE		256

struct pmapp_buf {
	char *start;		/* buffer start addr */
	char *end;		/* buffer end addr */
	int size;		/* buffer size */
	char *data;		/* payload begin addr */
	int len;		/* payload len */
};

static DEFINE_MUTEX(pmapp_mtx);

struct pmapp_ctrl {
	int inited;
	struct pmapp_buf tbuf;
	struct pmapp_buf rbuf;
	struct msm_rpc_endpoint *endpoint;
};

static struct pmapp_ctrl pmapp_ctrl = {
	.inited = -1,
};


static int pmapp_rpc_set_only(uint data0, uint data1, uint data2,
				uint data3, int num, int proc);

static int pmapp_buf_init(void)
{
	struct pmapp_ctrl *pm = &pmapp_ctrl;

	memset(&pmapp_ctrl, 0, sizeof(pmapp_ctrl));

	pm->tbuf.start = kmalloc(PMAPP_BUFF_SIZE, GFP_KERNEL);
	if (pm->tbuf.start == NULL) {
		printk(KERN_ERR "%s:%u\n", __func__, __LINE__);
		return -ENOMEM;
	}

	pm->tbuf.data = pm->tbuf.start;
	pm->tbuf.size = PMAPP_BUFF_SIZE;
	pm->tbuf.end = pm->tbuf.start + PMAPP_BUFF_SIZE;
	pm->tbuf.len = 0;

	pm->rbuf.start = kmalloc(PMAPP_BUFF_SIZE, GFP_KERNEL);
	if (pm->rbuf.start == NULL) {
		kfree(pm->tbuf.start);
		printk(KERN_ERR "%s:%u\n", __func__, __LINE__);
		return -ENOMEM;
	}
	pm->rbuf.data = pm->rbuf.start;
	pm->rbuf.size = PMAPP_BUFF_SIZE;
	pm->rbuf.end = pm->rbuf.start + PMAPP_BUFF_SIZE;
	pm->rbuf.len = 0;

	pm->inited = 1;

	return 0;
}

static inline void pmapp_buf_reserve(struct pmapp_buf *bp, int len)
{
	bp->data += len;
}

static inline void pmapp_buf_reset(struct pmapp_buf *bp)
{
	bp->data = bp->start;
	bp->len = 0;
}

static int modem_to_linux_err(uint err)
{
	if (err == 0)
		return 0;

	if (err & PM_ERR_FLAG__ALL_PARMS_OUT_OF_RANGE)
		return -EINVAL;	/* PM_ERR_FLAG__PAR[1..5]_OUT_OF_RANGE */

	if (err & PM_ERR_FLAG__SBI_OPT_ERR)
		return -EIO;

	if (err & PM_ERR_FLAG__FEATURE_NOT_SUPPORTED)
		return -ENOSYS;

	return -EPERM;
}

static int pmapp_put_tx_data(struct pmapp_buf *tp, uint datav)
{
	uint *lp;

	if ((tp->size - tp->len) < sizeof(datav)) {
		printk(KERN_ERR "%s: OVERFLOW size=%d len=%d\n",
					__func__, tp->size, tp->len);
		return -1;
	}

	lp = (uint *)tp->data;
	*lp = cpu_to_be32(datav);
	tp->data += sizeof(datav);
	tp->len += sizeof(datav);

	return sizeof(datav);
}

static int pmapp_pull_rx_data(struct pmapp_buf *rp, uint *datap)
{
	uint *lp;

	if (rp->len < sizeof(*datap)) {
		printk(KERN_ERR "%s: UNDERRUN len=%d\n", __func__, rp->len);
		return -1;
	}
	lp = (uint *)rp->data;
	*datap = be32_to_cpu(*lp);
	rp->data += sizeof(*datap);
	rp->len -= sizeof(*datap);

	return sizeof(*datap);
}


static int pmapp_rpc_req_reply(struct pmapp_buf *tbuf, struct pmapp_buf *rbuf,
	int	proc)
{
	struct pmapp_ctrl *pm = &pmapp_ctrl;
	int	ans, len, i;


	if ((pm->endpoint == NULL) || IS_ERR(pm->endpoint)) {
		for (i = 0; i < ARRAY_SIZE(rpc_vers); i++) {
			pm->endpoint = msm_rpc_connect_compatible(
					PMAPP_RPC_PROG,	rpc_vers[i], 0);

			if (IS_ERR(pm->endpoint)) {
				ans  = PTR_ERR(pm->endpoint);
				printk(KERN_ERR "%s: init rpc failed! ans = %d"
						" for 0x%x version, fallback\n",
						__func__, ans, rpc_vers[i]);
			} else {
				printk(KERN_DEBUG "%s: successfully connected"
					" to 0x%x rpc version\n",
					 __func__, rpc_vers[i]);
				break;
			}
		}
	}

	if (IS_ERR(pm->endpoint)) {
		ans  = PTR_ERR(pm->endpoint);
		return ans;
	}

	/*
	* data is point to next available space at this moment,
	* move it back to beginning of request header and increase
	* the length
	*/
	tbuf->data = tbuf->start;
	tbuf->len += sizeof(struct rpc_request_hdr);

	len = msm_rpc_call_reply(pm->endpoint, proc,
				tbuf->data, tbuf->len,
				rbuf->data, rbuf->size,
				PMAPP_RPC_TIMEOUT);

	if (len <= 0) {
		printk(KERN_ERR "%s: rpc failed! len = %d\n", __func__, len);
		pm->endpoint = NULL;	/* re-connect later ? */
		return len;
	}

	rbuf->len = len;
	/* strip off rpc_reply_hdr */
	rbuf->data += sizeof(struct rpc_reply_hdr);
	rbuf->len -= sizeof(struct rpc_reply_hdr);

	return rbuf->len;
}

static int pmapp_rpc_set_only(uint data0, uint data1, uint data2, uint data3,
		int num, int proc)
{
	struct pmapp_ctrl *pm = &pmapp_ctrl;
	struct pmapp_buf	*tp;
	struct pmapp_buf	*rp;
	int	stat;


	if (mutex_lock_interruptible(&pmapp_mtx))
		return -ERESTARTSYS;

	if (pm->inited <= 0) {
		stat = pmapp_buf_init();
		if (stat < 0) {
			mutex_unlock(&pmapp_mtx);
			return stat;
		}
	}

	tp = &pm->tbuf;
	rp = &pm->rbuf;

	pmapp_buf_reset(tp);
	pmapp_buf_reserve(tp, sizeof(struct rpc_request_hdr));
	pmapp_buf_reset(rp);

	if (num > 0)
		pmapp_put_tx_data(tp, data0);

	if (num > 1)
		pmapp_put_tx_data(tp, data1);

	if (num > 2)
		pmapp_put_tx_data(tp, data2);

	if (num > 3)
		pmapp_put_tx_data(tp, data3);

	stat = pmapp_rpc_req_reply(tp, rp, proc);
	if (stat < 0) {
		mutex_unlock(&pmapp_mtx);
		return stat;
	}

	pmapp_pull_rx_data(rp, &stat);	/* result from server */

	mutex_unlock(&pmapp_mtx);

	return modem_to_linux_err(stat);
}

int pmapp_display_clock_config(uint enable)
{
	return pmapp_rpc_set_only(enable, 0, 0, 0, 1,
			PMAPP_DISPLAY_CLOCK_CONFIG_PROC);
}
EXPORT_SYMBOL(pmapp_display_clock_config);

int pmapp_clock_vote(const char *voter_id, uint clock_id, uint vote)
{
	if (strlen(voter_id) != PMAPP_CLOCK_VOTER_ID_LEN)
		return -EINVAL;

	return pmapp_rpc_set_only(*((uint *) voter_id), clock_id, vote, 0, 3,
			PMAPP_CLOCK_VOTE_PROC);
}
EXPORT_SYMBOL(pmapp_clock_vote);

int pmapp_smps_clock_vote(const char *voter_id, uint vreg_id, uint vote)
{
	if (strlen(voter_id) != PMAPP_CLOCK_VOTER_ID_LEN)
		return -EINVAL;

	return pmapp_rpc_set_only(*((uint *) voter_id), vreg_id, vote, 0, 3,
				  PMAPP_SMPS_CLOCK_VOTE_PROC);
}
EXPORT_SYMBOL(pmapp_smps_clock_vote);

int pmapp_vreg_level_vote(const char *voter_id, uint vreg_id, uint level)
{
	if (strlen(voter_id) != PMAPP_CLOCK_VOTER_ID_LEN)
		return -EINVAL;

	return pmapp_rpc_set_only(*((uint *) voter_id), vreg_id, level, 0, 3,
				  PMAPP_VREG_LEVEL_VOTE_PROC);
}
EXPORT_SYMBOL(pmapp_vreg_level_vote);

int pmapp_smps_mode_vote(const char *voter_id, uint vreg_id, uint mode)
{
	if (strlen(voter_id) != PMAPP_CLOCK_VOTER_ID_LEN)
		return -EINVAL;

	return pmapp_rpc_set_only(*((uint *) voter_id), vreg_id, mode, 0, 3,
				  PMAPP_SMPS_MODE_VOTE_PROC);
}
EXPORT_SYMBOL(pmapp_smps_mode_vote);

int pmapp_vreg_pincntrl_vote(const char *voter_id, uint vreg_id,
						uint clock_id, uint vote)
{
	if (strlen(voter_id) != PMAPP_CLOCK_VOTER_ID_LEN)
		return -EINVAL;

	return pmapp_rpc_set_only(*((uint *) voter_id), vreg_id, clock_id,
					vote, 4,
					PMAPP_VREG_PINCNTRL_VOTE_PROC);
}
EXPORT_SYMBOL(pmapp_vreg_pincntrl_vote);

int pmapp_disp_backlight_set_brightness(int value)
{
	if (value < 0 || value > 100)
		return -EINVAL;

	return pmapp_rpc_set_only(value, 0, 0, 0, 1,
				PMAPP_DISP_BACKLIGHT_SET_PROC);
}
EXPORT_SYMBOL(pmapp_disp_backlight_set_brightness);

void pmapp_disp_backlight_init(void)
{
	pmapp_rpc_set_only(0, 0, 0, 0, 0, PMAPP_DISP_BACKLIGHT_INIT_PROC);
}
EXPORT_SYMBOL(pmapp_disp_backlight_init);

int pmapp_vreg_lpm_pincntrl_vote(const char *voter_id, uint vreg_id,
						uint clock_id, uint vote)
{
	if (strnlen(voter_id, PMAPP_CLOCK_VOTER_ID_LEN)
			 != PMAPP_CLOCK_VOTER_ID_LEN)
		return -EINVAL;

	return pmapp_rpc_set_only(*((uint *) voter_id), vreg_id, clock_id,
					vote, 4,
					PMAPP_VREG_LPM_PINCNTRL_VOTE_PROC);
}
EXPORT_SYMBOL(pmapp_vreg_lpm_pincntrl_vote);
