blob: 39ccdc2ecaa02b710c88f1ace05ce52724d31ec7 [file] [log] [blame]
Duy Truong790f06d2013-02-13 16:38:12 -08001/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#include <linux/err.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070014#include <linux/module.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070015#include <mach/rpc_hsusb.h>
16#include <mach/msm_hsusb.h>
17#include <mach/msm_rpcrouter.h>
18#include <mach/board.h>
19
20#define PM_APP_OTG_PROG 0x30000080
21#define PM_APP_OTG_VERS 0x00010001
22
23#define PM_APP_OTG_INIT_PHY 17
24#define PM_APP_OTG_RESET_PHY 18
25#define PM_APP_OTG_SUSPEND_PHY 7
26#define PM_APP_OTG_RESUME_PHY 8
27#define PM_APP_OTG_DEV_DISCONNECTED 9
28#define PM_APP_OTG_SET_WAKEUP 10
29#define PM_APP_OTG_ACQUIRE_BUS 3
30#define PM_APP_OTG_RELINQUISH_BUS 4
31
32#define PM_APP_OTG_INIT_DONE_CB_PROC 1
33#define PM_APP_OTG_HOST_INIT_CB_PROC 3
34#define PM_APP_OTG_REMOTE_DEV_LOST_CB_PROC 8
35#define PM_APP_OTG_REMOTE_DEV_RESUMED_CB_PROC 9
36#define PM_APP_OTG_ERROR_NOTIFY_CB_PROC 11
37
38#define NUM_OF_CALLBACKS 11
39static struct msm_rpc_client *client;
40static struct msm_otg_ops *host_ops;
41
42static int msm_fsusb_rpc_arg(struct msm_rpc_client *client,
43 void *buf, void *data)
44{
45 int i, size = 0;
46 uint32_t proc = *(uint32_t *)data;
47
48 switch (proc) {
49 case PM_APP_OTG_INIT_PHY: {
50 for (i = 0; i < NUM_OF_CALLBACKS; i++) {
51 *((uint32_t *)buf) = cpu_to_be32(0x11111111);
52 size += sizeof(uint32_t);
53 buf += sizeof(uint32_t);
54 }
55
56 /* sleep_assert callback fucntion will be registered locally*/
57 *((uint32_t *)buf) = cpu_to_be32(0xffffffff);
58 size += sizeof(uint32_t);
59 break;
60 }
61 case PM_APP_OTG_SET_WAKEUP: {
62 *((uint32_t *)buf) = cpu_to_be32(1);
63 size += sizeof(uint32_t);
64 break;
65 }
66 case PM_APP_OTG_ACQUIRE_BUS: {
67 *((uint32_t *)buf) = cpu_to_be32(0xffffffff);
68 size += sizeof(uint32_t);
69 break;
70 }
71 default:
72 pr_info("%s: No arguments expected\n", __func__);
73 }
74 return size;
75}
76
77int msm_fsusb_init_phy(void)
78{
79 uint32_t data = PM_APP_OTG_INIT_PHY;
80
81 return msm_rpc_client_req(client,
82 PM_APP_OTG_INIT_PHY,
83 msm_fsusb_rpc_arg, &data,
84 NULL, NULL, -1);
85}
86EXPORT_SYMBOL(msm_fsusb_init_phy);
87
88int msm_fsusb_reset_phy(void)
89{
90 return msm_rpc_client_req(client,
91 PM_APP_OTG_RESET_PHY,
92 NULL, NULL,
93 NULL, NULL, -1);
94
95}
96EXPORT_SYMBOL(msm_fsusb_reset_phy);
97
98int msm_fsusb_suspend_phy(void)
99{
100 return msm_rpc_client_req(client,
101 PM_APP_OTG_SUSPEND_PHY,
102 NULL, NULL,
103 NULL, NULL, -1);
104
105}
106EXPORT_SYMBOL(msm_fsusb_suspend_phy);
107
108int msm_fsusb_resume_phy(void)
109{
110 return msm_rpc_client_req(client,
111 PM_APP_OTG_RESUME_PHY,
112 NULL, NULL,
113 NULL, NULL, -1);
114
115}
116EXPORT_SYMBOL(msm_fsusb_resume_phy);
117
118int msm_fsusb_remote_dev_disconnected(void)
119{
120 return msm_rpc_client_req(client,
121 PM_APP_OTG_DEV_DISCONNECTED,
122 NULL, NULL,
123 NULL, NULL, -1);
124
125}
126EXPORT_SYMBOL(msm_fsusb_remote_dev_disconnected);
127
128int msm_fsusb_set_remote_wakeup(void)
129{
130 uint32_t data = PM_APP_OTG_SET_WAKEUP;
131
132 return msm_rpc_client_req(client,
133 PM_APP_OTG_SET_WAKEUP,
134 msm_fsusb_rpc_arg, &data,
135 NULL, NULL, -1);
136
137}
138EXPORT_SYMBOL(msm_fsusb_set_remote_wakeup);
139
140static int msm_fsusb_acquire_bus(void)
141{
142 uint32_t data = PM_APP_OTG_ACQUIRE_BUS;
143
144 return msm_rpc_client_req(client,
145 PM_APP_OTG_ACQUIRE_BUS,
146 msm_fsusb_rpc_arg, &data,
147 NULL, NULL, -1);
148
149}
150
151static int msm_fsusb_relinquish_bus(void)
152{
153 return msm_rpc_client_req(client,
154 PM_APP_OTG_RELINQUISH_BUS,
155 NULL, NULL,
156 NULL, NULL, -1);
157
158}
159
160static void msm_fsusb_request_session(void)
161{
162 int ret;
163
164 ret = msm_fsusb_relinquish_bus();
165 if (ret < 0)
166 pr_err("relinquish_bus rpc failed\n");
167 ret = msm_fsusb_acquire_bus();
168 if (ret < 0)
169 pr_err("acquire_bus rpc failed\n");
170}
171
172static int msm_fsusb_cb_func(struct msm_rpc_client *client,
173 void *buffer, int in_size)
174{
175 struct rpc_request_hdr *req;
176 int rc;
177
178 req = buffer;
179
180 msm_rpc_start_accepted_reply(client, be32_to_cpu(req->xid),
181 RPC_ACCEPTSTAT_SUCCESS);
182 rc = msm_rpc_send_accepted_reply(client, 0);
183 if (rc) {
184 pr_err("%s: sending reply failed: %d\n", __func__, rc);
185 return rc;
186 }
187
188 switch (be32_to_cpu(req->procedure)) {
189 case PM_APP_OTG_INIT_DONE_CB_PROC: {
190 pr_debug("pm_app_otg_init_done callback received");
191 msm_fsusb_request_session();
192 break;
193 }
194 case PM_APP_OTG_HOST_INIT_CB_PROC: {
195 pr_debug("pm_app_otg_host_init_cb_proc callback received");
196 host_ops->request(host_ops->handle, REQUEST_START);
197 break;
198 }
199 case PM_APP_OTG_REMOTE_DEV_LOST_CB_PROC: {
200 pr_debug("pm_app_otg_remote_dev_lost_cb_proc"
201 " callback received");
202 msm_fsusb_acquire_bus();
203 host_ops->request(host_ops->handle, REQUEST_STOP);
204 break;
205 }
206 case PM_APP_OTG_REMOTE_DEV_RESUMED_CB_PROC: {
207 pr_debug("pm_app_otg_remote_dev_resumed_cb_proc"
208 "callback received");
209 host_ops->request(host_ops->handle, REQUEST_RESUME);
210 break;
211 }
212 case PM_APP_OTG_ERROR_NOTIFY_CB_PROC: {
213 pr_err("pm_app_otg_error_notify_cb_proc callback received");
214 break;
215 }
216 default:
217 pr_err("%s: unknown callback(proc = %d) received\n",
218 __func__, req->procedure);
219 }
220 return 0;
221}
222
223int msm_fsusb_rpc_init(struct msm_otg_ops *ops)
224{
225 host_ops = ops;
226 client = msm_rpc_register_client("fsusb",
227 PM_APP_OTG_PROG,
228 PM_APP_OTG_VERS, 1,
229 msm_fsusb_cb_func);
230 if (IS_ERR(client)) {
231 pr_err("%s: couldn't open rpc client\n", __func__);
232 return PTR_ERR(client);
233 }
234
235 return 0;
236
237}
238EXPORT_SYMBOL(msm_fsusb_rpc_init);
239
240void msm_fsusb_rpc_deinit(void)
241{
242 msm_rpc_unregister_client(client);
243}
244EXPORT_SYMBOL(msm_fsusb_rpc_deinit);