1 /* arch/arm/mach-msm/qdsp5/audmgr.c
3 * interface to "audmgr" service on the baseband cpu
5 * Copyright (C) 2008 Google, Inc.
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
18 #include <linux/module.h>
20 #include <linux/uaccess.h>
21 #include <linux/slab.h>
22 #include <linux/kthread.h>
23 #include <linux/wait.h>
25 #include <asm/atomic.h>
26 #include <mach/msm_rpcrouter.h>
30 #define STATE_CLOSED 0
31 #define STATE_DISABLED 1
32 #define STATE_ENABLING 2
33 #define STATE_ENABLED 3
34 #define STATE_DISABLING 4
37 static void rpc_ack(struct msm_rpc_endpoint
*ept
, uint32_t xid
)
41 rep
[0] = cpu_to_be32(xid
);
42 rep
[1] = cpu_to_be32(1);
43 rep
[2] = cpu_to_be32(RPCMSG_REPLYSTAT_ACCEPTED
);
44 rep
[3] = cpu_to_be32(RPC_ACCEPTSTAT_SUCCESS
);
48 msm_rpc_write(ept
, rep
, sizeof(rep
));
51 static void process_audmgr_callback(struct audmgr
*am
,
52 struct rpc_audmgr_cb_func_ptr
*args
,
55 if (len
< (sizeof(uint32_t) * 3))
57 if (be32_to_cpu(args
->set_to_one
) != 1)
60 switch (be32_to_cpu(args
->status
)) {
61 case RPC_AUDMGR_STATUS_READY
:
62 if (len
< sizeof(uint32_t) * 4)
64 am
->handle
= be32_to_cpu(args
->u
.handle
);
65 pr_info("audmgr: rpc READY handle=0x%08x\n", am
->handle
);
67 case RPC_AUDMGR_STATUS_CODEC_CONFIG
: {
69 if (len
< sizeof(uint32_t) * 4)
71 volume
= be32_to_cpu(args
->u
.volume
);
72 pr_info("audmgr: rpc CODEC_CONFIG volume=0x%08x\n", volume
);
73 am
->state
= STATE_ENABLED
;
77 case RPC_AUDMGR_STATUS_PENDING
:
78 pr_err("audmgr: PENDING?\n");
80 case RPC_AUDMGR_STATUS_SUSPEND
:
81 pr_err("audmgr: SUSPEND?\n");
83 case RPC_AUDMGR_STATUS_FAILURE
:
84 pr_err("audmgr: FAILURE\n");
86 case RPC_AUDMGR_STATUS_VOLUME_CHANGE
:
87 pr_err("audmgr: VOLUME_CHANGE?\n");
89 case RPC_AUDMGR_STATUS_DISABLED
:
90 pr_err("audmgr: DISABLED\n");
91 am
->state
= STATE_DISABLED
;
94 case RPC_AUDMGR_STATUS_ERROR
:
95 pr_err("audmgr: ERROR?\n");
96 am
->state
= STATE_ERROR
;
104 static void process_rpc_request(uint32_t proc
, uint32_t xid
,
105 void *data
, int len
, void *private)
107 struct audmgr
*am
= private;
112 pr_info("rpc_call proc %d:", proc
);
114 printk(" %08x", be32_to_cpu(*x
++));
118 if (proc
== AUDMGR_CB_FUNC_PTR
)
119 process_audmgr_callback(am
, data
, len
);
121 pr_err("audmgr: unknown rpc proc %d\n", proc
);
122 rpc_ack(am
->ept
, xid
);
125 #define RPC_TYPE_REQUEST 0
126 #define RPC_TYPE_REPLY 1
128 #define RPC_VERSION 2
130 #define RPC_COMMON_HDR_SZ (sizeof(uint32_t) * 2)
131 #define RPC_REQUEST_HDR_SZ (sizeof(struct rpc_request_hdr))
132 #define RPC_REPLY_HDR_SZ (sizeof(uint32_t) * 3)
133 #define RPC_REPLY_SZ (sizeof(uint32_t) * 6)
135 static int audmgr_rpc_thread(void *data
)
137 struct audmgr
*am
= data
;
138 struct rpc_request_hdr
*hdr
= NULL
;
142 pr_info("audmgr_rpc_thread() start\n");
144 while (!kthread_should_stop()) {
149 len
= msm_rpc_read(am
->ept
, (void **) &hdr
, -1, -1);
151 pr_err("audmgr: rpc read failed (%d)\n", len
);
154 if (len
< RPC_COMMON_HDR_SZ
)
157 type
= be32_to_cpu(hdr
->type
);
158 if (type
== RPC_TYPE_REPLY
) {
159 struct rpc_reply_hdr
*rep
= (void *) hdr
;
161 if (len
< RPC_REPLY_HDR_SZ
)
163 status
= be32_to_cpu(rep
->reply_stat
);
164 if (status
== RPCMSG_REPLYSTAT_ACCEPTED
) {
165 status
= be32_to_cpu(rep
->data
.acc_hdr
.accept_stat
);
166 pr_info("audmgr: rpc_reply status %d\n", status
);
168 pr_info("audmgr: rpc_reply denied!\n");
174 if (len
< RPC_REQUEST_HDR_SZ
)
177 process_rpc_request(be32_to_cpu(hdr
->procedure
),
178 be32_to_cpu(hdr
->xid
),
183 pr_info("audmgr_rpc_thread() exit\n");
193 struct audmgr_enable_msg
{
194 struct rpc_request_hdr hdr
;
195 struct rpc_audmgr_enable_client_args args
;
198 struct audmgr_disable_msg
{
199 struct rpc_request_hdr hdr
;
203 int audmgr_open(struct audmgr
*am
)
207 if (am
->state
!= STATE_CLOSED
)
210 am
->ept
= msm_rpc_connect(AUDMGR_PROG
,
212 MSM_RPC_UNINTERRUPTIBLE
);
214 init_waitqueue_head(&am
->wait
);
216 if (IS_ERR(am
->ept
)) {
217 rc
= PTR_ERR(am
->ept
);
219 pr_err("audmgr: failed to connect to audmgr svc\n");
223 am
->task
= kthread_run(audmgr_rpc_thread
, am
, "audmgr_rpc");
224 if (IS_ERR(am
->task
)) {
225 rc
= PTR_ERR(am
->task
);
227 msm_rpc_close(am
->ept
);
232 am
->state
= STATE_DISABLED
;
235 EXPORT_SYMBOL(audmgr_open
);
237 int audmgr_close(struct audmgr
*am
)
241 EXPORT_SYMBOL(audmgr_close
);
243 int audmgr_enable(struct audmgr
*am
, struct audmgr_config
*cfg
)
245 struct audmgr_enable_msg msg
;
248 if (am
->state
== STATE_ENABLED
)
251 if (am
->state
== STATE_DISABLING
)
252 pr_err("audmgr: state is DISABLING in enable?\n");
253 am
->state
= STATE_ENABLING
;
255 msg
.args
.set_to_one
= cpu_to_be32(1);
256 msg
.args
.tx_sample_rate
= cpu_to_be32(cfg
->tx_rate
);
257 msg
.args
.rx_sample_rate
= cpu_to_be32(cfg
->rx_rate
);
258 msg
.args
.def_method
= cpu_to_be32(cfg
->def_method
);
259 msg
.args
.codec_type
= cpu_to_be32(cfg
->codec
);
260 msg
.args
.snd_method
= cpu_to_be32(cfg
->snd_method
);
261 msg
.args
.cb_func
= cpu_to_be32(0x11111111);
262 msg
.args
.client_data
= cpu_to_be32(0x11223344);
264 msm_rpc_setup_req(&msg
.hdr
, AUDMGR_PROG
, msm_rpc_get_vers(am
->ept
),
265 AUDMGR_ENABLE_CLIENT
);
267 rc
= msm_rpc_write(am
->ept
, &msg
, sizeof(msg
));
271 rc
= wait_event_timeout(am
->wait
, am
->state
!= STATE_ENABLING
, 15 * HZ
);
273 pr_err("audmgr_enable: ARM9 did not reply to RPC am->state = %d\n", am
->state
);
276 if (am
->state
== STATE_ENABLED
)
279 pr_err("audmgr: unexpected state %d while enabling?!\n", am
->state
);
282 EXPORT_SYMBOL(audmgr_enable
);
284 int audmgr_disable(struct audmgr
*am
)
286 struct audmgr_disable_msg msg
;
289 if (am
->state
== STATE_DISABLED
)
292 msm_rpc_setup_req(&msg
.hdr
, AUDMGR_PROG
, msm_rpc_get_vers(am
->ept
),
293 AUDMGR_DISABLE_CLIENT
);
294 msg
.handle
= cpu_to_be32(am
->handle
);
296 am
->state
= STATE_DISABLING
;
298 rc
= msm_rpc_write(am
->ept
, &msg
, sizeof(msg
));
302 rc
= wait_event_timeout(am
->wait
, am
->state
!= STATE_DISABLING
, 15 * HZ
);
304 pr_err("audmgr_disable: ARM9 did not reply to RPC am->state = %d\n", am
->state
);
308 if (am
->state
== STATE_DISABLED
)
311 pr_err("audmgr: unexpected state %d while disabling?!\n", am
->state
);
314 EXPORT_SYMBOL(audmgr_disable
);