Initial Contribution

msm-2.6.38: tag AU_LINUX_ANDROID_GINGERBREAD.02.03.04.00.142

Signed-off-by: Bryan Huntsman <bryanh@codeaurora.org>
diff --git a/arch/arm/mach-msm/rpc_fsusb.c b/arch/arm/mach-msm/rpc_fsusb.c
new file mode 100644
index 0000000..1fd33de
--- /dev/null
+++ b/arch/arm/mach-msm/rpc_fsusb.c
@@ -0,0 +1,243 @@
+/* Copyright (c) 2009, 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/err.h>
+#include <mach/rpc_hsusb.h>
+#include <mach/msm_hsusb.h>
+#include <mach/msm_rpcrouter.h>
+#include <mach/board.h>
+
+#define PM_APP_OTG_PROG		0x30000080
+#define PM_APP_OTG_VERS		0x00010001
+
+#define PM_APP_OTG_INIT_PHY			17
+#define PM_APP_OTG_RESET_PHY			18
+#define PM_APP_OTG_SUSPEND_PHY			7
+#define PM_APP_OTG_RESUME_PHY			8
+#define PM_APP_OTG_DEV_DISCONNECTED		9
+#define PM_APP_OTG_SET_WAKEUP			10
+#define PM_APP_OTG_ACQUIRE_BUS			3
+#define PM_APP_OTG_RELINQUISH_BUS		4
+
+#define PM_APP_OTG_INIT_DONE_CB_PROC		1
+#define PM_APP_OTG_HOST_INIT_CB_PROC		3
+#define PM_APP_OTG_REMOTE_DEV_LOST_CB_PROC	8
+#define PM_APP_OTG_REMOTE_DEV_RESUMED_CB_PROC	9
+#define PM_APP_OTG_ERROR_NOTIFY_CB_PROC		11
+
+#define NUM_OF_CALLBACKS			11
+static struct msm_rpc_client *client;
+static struct msm_otg_ops *host_ops;
+
+static int msm_fsusb_rpc_arg(struct msm_rpc_client *client,
+			     void *buf, void *data)
+{
+	int i, size = 0;
+	uint32_t proc = *(uint32_t *)data;
+
+	switch (proc) {
+	case PM_APP_OTG_INIT_PHY: {
+		for (i = 0; i < NUM_OF_CALLBACKS; i++) {
+			*((uint32_t *)buf) = cpu_to_be32(0x11111111);
+			size += sizeof(uint32_t);
+			buf += sizeof(uint32_t);
+		}
+
+		/* sleep_assert callback fucntion will be registered locally*/
+		*((uint32_t *)buf) = cpu_to_be32(0xffffffff);
+		size += sizeof(uint32_t);
+		break;
+	}
+	case PM_APP_OTG_SET_WAKEUP: {
+			*((uint32_t *)buf) = cpu_to_be32(1);
+			size += sizeof(uint32_t);
+			break;
+	}
+	case PM_APP_OTG_ACQUIRE_BUS: {
+			*((uint32_t *)buf) = cpu_to_be32(0xffffffff);
+			size += sizeof(uint32_t);
+			break;
+	}
+	default:
+		pr_info("%s: No arguments expected\n", __func__);
+	}
+	return size;
+}
+
+int msm_fsusb_init_phy(void)
+{
+	uint32_t data = PM_APP_OTG_INIT_PHY;
+
+	return msm_rpc_client_req(client,
+			PM_APP_OTG_INIT_PHY,
+			msm_fsusb_rpc_arg, &data,
+			NULL, NULL, -1);
+}
+EXPORT_SYMBOL(msm_fsusb_init_phy);
+
+int msm_fsusb_reset_phy(void)
+{
+	return msm_rpc_client_req(client,
+			PM_APP_OTG_RESET_PHY,
+			NULL, NULL,
+			NULL, NULL, -1);
+
+}
+EXPORT_SYMBOL(msm_fsusb_reset_phy);
+
+int msm_fsusb_suspend_phy(void)
+{
+	return msm_rpc_client_req(client,
+			PM_APP_OTG_SUSPEND_PHY,
+			NULL, NULL,
+			NULL, NULL, -1);
+
+}
+EXPORT_SYMBOL(msm_fsusb_suspend_phy);
+
+int msm_fsusb_resume_phy(void)
+{
+	return msm_rpc_client_req(client,
+			PM_APP_OTG_RESUME_PHY,
+			NULL, NULL,
+			NULL, NULL, -1);
+
+}
+EXPORT_SYMBOL(msm_fsusb_resume_phy);
+
+int msm_fsusb_remote_dev_disconnected(void)
+{
+	return msm_rpc_client_req(client,
+			PM_APP_OTG_DEV_DISCONNECTED,
+			NULL, NULL,
+			NULL, NULL, -1);
+
+}
+EXPORT_SYMBOL(msm_fsusb_remote_dev_disconnected);
+
+int  msm_fsusb_set_remote_wakeup(void)
+{
+	uint32_t data = PM_APP_OTG_SET_WAKEUP;
+
+	return msm_rpc_client_req(client,
+			PM_APP_OTG_SET_WAKEUP,
+			msm_fsusb_rpc_arg, &data,
+			NULL, NULL, -1);
+
+}
+EXPORT_SYMBOL(msm_fsusb_set_remote_wakeup);
+
+static int msm_fsusb_acquire_bus(void)
+{
+	uint32_t data = PM_APP_OTG_ACQUIRE_BUS;
+
+	return msm_rpc_client_req(client,
+			PM_APP_OTG_ACQUIRE_BUS,
+			msm_fsusb_rpc_arg, &data,
+			NULL, NULL, -1);
+
+}
+
+static int msm_fsusb_relinquish_bus(void)
+{
+	return msm_rpc_client_req(client,
+			PM_APP_OTG_RELINQUISH_BUS,
+			NULL, NULL,
+			NULL, NULL, -1);
+
+}
+
+static void msm_fsusb_request_session(void)
+{
+	int ret;
+
+	ret = msm_fsusb_relinquish_bus();
+	if (ret < 0)
+		pr_err("relinquish_bus rpc failed\n");
+	ret = msm_fsusb_acquire_bus();
+	if (ret < 0)
+		pr_err("acquire_bus rpc failed\n");
+}
+
+static int msm_fsusb_cb_func(struct msm_rpc_client *client,
+			    void *buffer, int in_size)
+{
+	struct rpc_request_hdr *req;
+	int rc;
+
+	req = buffer;
+
+	msm_rpc_start_accepted_reply(client, be32_to_cpu(req->xid),
+				     RPC_ACCEPTSTAT_SUCCESS);
+	rc = msm_rpc_send_accepted_reply(client, 0);
+	if (rc) {
+		pr_err("%s: sending reply failed: %d\n", __func__, rc);
+		return rc;
+	}
+
+	switch (be32_to_cpu(req->procedure)) {
+	case PM_APP_OTG_INIT_DONE_CB_PROC: {
+		pr_debug("pm_app_otg_init_done callback received");
+		msm_fsusb_request_session();
+		break;
+	}
+	case PM_APP_OTG_HOST_INIT_CB_PROC: {
+		pr_debug("pm_app_otg_host_init_cb_proc callback received");
+		host_ops->request(host_ops->handle, REQUEST_START);
+		break;
+	}
+	case PM_APP_OTG_REMOTE_DEV_LOST_CB_PROC: {
+		pr_debug("pm_app_otg_remote_dev_lost_cb_proc"
+				" callback received");
+		msm_fsusb_acquire_bus();
+		host_ops->request(host_ops->handle, REQUEST_STOP);
+		break;
+	}
+	case PM_APP_OTG_REMOTE_DEV_RESUMED_CB_PROC: {
+		pr_debug("pm_app_otg_remote_dev_resumed_cb_proc"
+				"callback received");
+		host_ops->request(host_ops->handle, REQUEST_RESUME);
+		break;
+	}
+	case PM_APP_OTG_ERROR_NOTIFY_CB_PROC: {
+		pr_err("pm_app_otg_error_notify_cb_proc callback received");
+		break;
+	}
+	default:
+		pr_err("%s: unknown callback(proc = %d) received\n",
+					__func__, req->procedure);
+	}
+	return 0;
+}
+
+int msm_fsusb_rpc_init(struct msm_otg_ops *ops)
+{
+	host_ops = ops;
+	client = msm_rpc_register_client("fsusb",
+			PM_APP_OTG_PROG,
+			PM_APP_OTG_VERS, 1,
+			msm_fsusb_cb_func);
+	if (IS_ERR(client)) {
+		pr_err("%s: couldn't open rpc client\n", __func__);
+		return PTR_ERR(client);
+	}
+
+	return 0;
+
+}
+EXPORT_SYMBOL(msm_fsusb_rpc_init);
+
+void msm_fsusb_rpc_deinit(void)
+{
+	msm_rpc_unregister_client(client);
+}
+EXPORT_SYMBOL(msm_fsusb_rpc_deinit);