blob: fddf34f6895fbf5a6b822740c24ba2e916d7dcf8 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001
2/*
3 * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
4 * Author: Brian Swetland <swetland@google.com>
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16#include <linux/fs.h>
17#include <linux/mutex.h>
18#include <linux/wait.h>
19#include <linux/miscdevice.h>
20#include <linux/uaccess.h>
21#include <linux/sched.h>
22#include <linux/dma-mapping.h>
23#include <linux/miscdevice.h>
24#include <linux/delay.h>
25#include <linux/spinlock.h>
26#include <linux/slab.h>
27#include <linux/msm_audio.h>
28#include <linux/android_pmem.h>
29#include <linux/memory_alloc.h>
30#include <mach/memory.h>
31#include <mach/debug_mm.h>
32#include <mach/peripheral-loader.h>
33#include <mach/qdsp6v2/audio_acdb.h>
34#include <mach/qdsp6v2/rtac.h>
35#include <mach/msm_subsystem_map.h>
36#include <sound/apr_audio.h>
37#include <sound/q6asm.h>
38#include <asm/atomic.h>
39#include <asm/ioctls.h>
Rajesha Kini3498c932011-07-19 19:58:27 +053040#include <linux/debugfs.h>
41#include <linux/time.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070042
43#define TRUE 0x01
44#define FALSE 0x00
45#define READDONE_IDX_STATUS 0
46#define READDONE_IDX_BUFFER 1
47#define READDONE_IDX_SIZE 2
48#define READDONE_IDX_OFFSET 3
49#define READDONE_IDX_MSW_TS 4
50#define READDONE_IDX_LSW_TS 5
51#define READDONE_IDX_FLAGS 6
52#define READDONE_IDX_NUMFRAMES 7
53#define READDONE_IDX_ID 8
Rajesha Kini3498c932011-07-19 19:58:27 +053054#ifdef CONFIG_DEBUG_FS
55#define OUT_BUFFER_SIZE 56
56#define IN_BUFFER_SIZE 24
57#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070058static DEFINE_MUTEX(session_lock);
59
60/* session id: 0 reserved */
61static struct audio_client *session[SESSION_MAX+1];
62static int32_t q6asm_mmapcallback(struct apr_client_data *data, void *priv);
63static int32_t q6asm_callback(struct apr_client_data *data, void *priv);
64static void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
65 uint32_t pkt_size, uint32_t cmd_flg);
66static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr,
67 uint32_t pkt_size, uint32_t cmd_flg);
68static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
69 uint32_t bufsz, uint32_t bufcnt);
70static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir,
71 uint32_t bufsz, uint32_t bufcnt);
72
73static void q6asm_reset_buf_state(struct audio_client *ac);
74
Rajesha Kini3498c932011-07-19 19:58:27 +053075#ifdef CONFIG_DEBUG_FS
76static struct timeval out_cold_tv;
77static struct timeval out_warm_tv;
78static struct timeval out_cont_tv;
79static struct timeval in_cont_tv;
80static long out_enable_flag;
81static long in_enable_flag;
82static struct dentry *out_dentry;
83static struct dentry *in_dentry;
84static int in_cont_index;
85/*This var is used to keep track of first write done for cold output latency */
86static int out_cold_index;
87static char *out_buffer;
88static char *in_buffer;
89static int audio_output_latency_dbgfs_open(struct inode *inode,
90 struct file *file)
91{
92 file->private_data = inode->i_private;
93 return 0;
94}
95static ssize_t audio_output_latency_dbgfs_read(struct file *file,
96 char __user *buf, size_t count, loff_t *ppos)
97{
98 snprintf(out_buffer, OUT_BUFFER_SIZE, "%ld,%ld,%ld,%ld,%ld,%ld,",\
99 out_cold_tv.tv_sec, out_cold_tv.tv_usec, out_warm_tv.tv_sec,\
100 out_warm_tv.tv_usec, out_cont_tv.tv_sec, out_cont_tv.tv_usec);
101 return simple_read_from_buffer(buf, OUT_BUFFER_SIZE, ppos,
102 out_buffer, OUT_BUFFER_SIZE);
103}
104static ssize_t audio_output_latency_dbgfs_write(struct file *file,
105 const char __user *buf, size_t count, loff_t *ppos)
106{
107 char *temp;
108
109 if (count > 2*sizeof(char))
110 return -EINVAL;
111 else
112 temp = kmalloc(2*sizeof(char), GFP_KERNEL);
113
114 out_cold_index = 0;
115
116 if (temp) {
117 if (copy_from_user(temp, buf, 2*sizeof(char))) {
118 kfree(temp);
119 return -EFAULT;
120 }
121 if (!strict_strtol(temp, 10, &out_enable_flag)) {
122 kfree(temp);
123 return count;
124 }
125 kfree(temp);
126 }
127 return -EINVAL;
128}
129static const struct file_operations audio_output_latency_debug_fops = {
130 .open = audio_output_latency_dbgfs_open,
131 .read = audio_output_latency_dbgfs_read,
132 .write = audio_output_latency_dbgfs_write
133};
134
135static int audio_input_latency_dbgfs_open(struct inode *inode,
136 struct file *file)
137{
138 file->private_data = inode->i_private;
139 return 0;
140}
141static ssize_t audio_input_latency_dbgfs_read(struct file *file,
142 char __user *buf, size_t count, loff_t *ppos)
143{
144 snprintf(in_buffer, IN_BUFFER_SIZE, "%ld,%ld,",\
145 in_cont_tv.tv_sec, in_cont_tv.tv_usec);
146 return simple_read_from_buffer(buf, IN_BUFFER_SIZE, ppos,
147 in_buffer, IN_BUFFER_SIZE);
148}
149static ssize_t audio_input_latency_dbgfs_write(struct file *file,
150 const char __user *buf, size_t count, loff_t *ppos)
151{
152 char *temp;
153
154 if (count > 2*sizeof(char))
155 return -EINVAL;
156 else
157 temp = kmalloc(2*sizeof(char), GFP_KERNEL);
158 if (temp) {
159 if (copy_from_user(temp, buf, 2*sizeof(char))) {
160 kfree(temp);
161 return -EFAULT;
162 }
163 if (!strict_strtol(temp, 10, &in_enable_flag)) {
164 kfree(temp);
165 return count;
166 }
167 kfree(temp);
168 }
169 return -EINVAL;
170}
171static const struct file_operations audio_input_latency_debug_fops = {
172 .open = audio_input_latency_dbgfs_open,
173 .read = audio_input_latency_dbgfs_read,
174 .write = audio_input_latency_dbgfs_write
175};
176#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700177struct asm_mmap {
178 atomic_t ref_cnt;
179 atomic_t cmd_state;
180 wait_queue_head_t cmd_wait;
181 void *apr;
182};
183
184static struct asm_mmap this_mmap;
185
186static int q6asm_session_alloc(struct audio_client *ac)
187{
188 int n;
189 mutex_lock(&session_lock);
190 for (n = 1; n <= SESSION_MAX; n++) {
191 if (!session[n]) {
192 session[n] = ac;
193 mutex_unlock(&session_lock);
194 return n;
195 }
196 }
197 mutex_unlock(&session_lock);
198 return -ENOMEM;
199}
200
201static void q6asm_session_free(struct audio_client *ac)
202{
203 pr_debug("%s: sessionid[%d]\n", __func__, ac->session);
204 mutex_lock(&session_lock);
205 session[ac->session] = 0;
206 mutex_unlock(&session_lock);
207 ac->session = 0;
208 return;
209}
210
211int q6asm_audio_client_buf_free(unsigned int dir,
212 struct audio_client *ac)
213{
214 struct audio_port_data *port;
215 int cnt = 0;
216 int rc = 0;
217 pr_debug("%s: Session id %d\n", __func__, ac->session);
218 mutex_lock(&ac->cmd_lock);
219 if (ac->io_mode == SYNC_IO_MODE) {
220 port = &ac->port[dir];
221 if (!port->buf) {
222 mutex_unlock(&ac->cmd_lock);
223 return 0;
224 }
225 cnt = port->max_buf_cnt - 1;
226
227 if (cnt >= 0) {
228 rc = q6asm_memory_unmap_regions(ac, dir,
229 port->buf[0].size,
230 port->max_buf_cnt);
231 if (rc < 0)
232 pr_err("%s CMD Memory_unmap_regions failed\n",
233 __func__);
234 }
235
236 while (cnt >= 0) {
237 if (port->buf[cnt].data) {
238 pr_debug("%s:data[%p]phys[%p][%p] cnt[%d]"
239 "mem_buffer[%p]\n",
240 __func__, (void *)port->buf[cnt].data,
241 (void *)port->buf[cnt].phys,
242 (void *)&port->buf[cnt].phys, cnt,
243 (void *)port->buf[cnt].mem_buffer);
244 if (IS_ERR((void *)port->buf[cnt].mem_buffer))
245 pr_err("%s:mem buffer invalid, error ="
246 "%ld\n", __func__,
247 PTR_ERR((void *)port->buf[cnt].mem_buffer));
248 else {
249 if (msm_subsystem_unmap_buffer(
250 port->buf[cnt].mem_buffer) < 0)
251 pr_err("%s: unmap buffer"
252 " failed\n", __func__);
253 }
254 free_contiguous_memory_by_paddr(
255 port->buf[cnt].phys);
256
257 port->buf[cnt].data = NULL;
258 port->buf[cnt].phys = 0;
259 --(port->max_buf_cnt);
260 }
261 --cnt;
262 }
263 kfree(port->buf);
264 port->buf = NULL;
265 }
266 mutex_unlock(&ac->cmd_lock);
267 return 0;
268}
269
270int q6asm_audio_client_buf_free_contiguous(unsigned int dir,
271 struct audio_client *ac)
272{
273 struct audio_port_data *port;
274 int cnt = 0;
275 int rc = 0;
276 pr_debug("%s: Session id %d\n", __func__, ac->session);
277 mutex_lock(&ac->cmd_lock);
278 port = &ac->port[dir];
279 if (!port->buf) {
280 mutex_unlock(&ac->cmd_lock);
281 return 0;
282 }
283 cnt = port->max_buf_cnt - 1;
284
285 if (cnt >= 0) {
Deepa Madiregama7d52a402011-07-13 20:28:36 +0530286 rc = q6asm_memory_unmap(ac, port->buf[0].phys, dir);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700287 if (rc < 0)
288 pr_err("%s CMD Memory_unmap_regions failed\n",
289 __func__);
290 }
291
292 if (port->buf[0].data) {
293 pr_debug("%s:data[%p]phys[%p][%p] cnt[%d]\n",
294 __func__,
295 (void *)port->buf[0].data,
296 (void *)port->buf[0].phys,
297 (void *)&port->buf[0].phys, cnt);
298 dma_free_coherent(NULL,
299 port->buf[0].size * port->max_buf_cnt,
300 port->buf[0].data,
301 port->buf[0].phys);
302 }
303 while (cnt >= 0) {
304 port->buf[cnt].data = NULL;
305 port->buf[cnt].phys = 0;
306 cnt--;
307 }
308 port->max_buf_cnt = 0;
309 kfree(port->buf);
310 port->buf = NULL;
311 mutex_unlock(&ac->cmd_lock);
312 return 0;
313}
314
315void q6asm_audio_client_free(struct audio_client *ac)
316{
317 int loopcnt;
318 struct audio_port_data *port;
319 if (!ac || !ac->session)
320 return;
321 pr_debug("%s: Session id %d\n", __func__, ac->session);
322 if (ac->io_mode == SYNC_IO_MODE) {
323 for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
324 port = &ac->port[loopcnt];
325 if (!port->buf)
326 continue;
327 pr_debug("%s:loopcnt = %d\n", __func__, loopcnt);
328 q6asm_audio_client_buf_free(loopcnt, ac);
329 }
330 }
331
332 apr_deregister(ac->apr);
333 q6asm_session_free(ac);
334
335 pr_debug("%s: APR De-Register\n", __func__);
336 if (atomic_read(&this_mmap.ref_cnt) <= 0) {
337 pr_err("%s: APR Common Port Already Closed\n", __func__);
338 goto done;
339 }
340
341 atomic_dec(&this_mmap.ref_cnt);
342 if (atomic_read(&this_mmap.ref_cnt) == 0) {
343 apr_deregister(this_mmap.apr);
344 pr_debug("%s:APR De-Register common port\n", __func__);
345 }
346done:
347 kfree(ac);
348 return;
349}
350
351int q6asm_set_io_mode(struct audio_client *ac, uint32_t mode)
352{
353 if (ac == NULL) {
354 pr_err("%s APR handle NULL\n", __func__);
355 return -EINVAL;
356 }
357 if ((mode == ASYNC_IO_MODE) || (mode == SYNC_IO_MODE)) {
358 ac->io_mode = mode;
359 pr_debug("%s:Set Mode to %d\n", __func__, ac->io_mode);
360 return 0;
361 } else {
362 pr_err("%s:Not an valid IO Mode:%d\n", __func__, ac->io_mode);
363 return -EINVAL;
364 }
365}
366
367struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv)
368{
369 struct audio_client *ac;
370 int n;
371 int lcnt = 0;
372
373 ac = kzalloc(sizeof(struct audio_client), GFP_KERNEL);
374 if (!ac)
375 return NULL;
376 n = q6asm_session_alloc(ac);
377 if (n <= 0)
378 goto fail_session;
379 ac->session = n;
380 ac->cb = cb;
381 ac->priv = priv;
382 ac->io_mode = SYNC_IO_MODE;
383 ac->apr = apr_register("ADSP", "ASM", \
384 (apr_fn)q6asm_callback,\
385 ((ac->session) << 8 | 0x0001),\
386 ac);
387
388 if (ac->apr == NULL) {
389 pr_err("%s Registration with APR failed\n", __func__);
390 goto fail;
391 }
392#ifdef CONFIG_MSM8X60_RTAC
393 rtac_set_asm_handle(n, ac->apr);
394#endif
395 pr_debug("%s Registering the common port with APR\n", __func__);
396 if (atomic_read(&this_mmap.ref_cnt) == 0) {
397 this_mmap.apr = apr_register("ADSP", "ASM", \
398 (apr_fn)q6asm_mmapcallback,\
399 0x0FFFFFFFF, &this_mmap);
400 if (this_mmap.apr == NULL) {
401 pr_debug("%s Unable to register \
402 APR ASM common port \n", __func__);
403 goto fail;
404 }
405 }
406
407 atomic_inc(&this_mmap.ref_cnt);
408 init_waitqueue_head(&ac->cmd_wait);
409 init_waitqueue_head(&ac->time_wait);
410 atomic_set(&ac->time_flag, 1);
411 mutex_init(&ac->cmd_lock);
412 for (lcnt = 0; lcnt <= OUT; lcnt++) {
413 mutex_init(&ac->port[lcnt].lock);
414 spin_lock_init(&ac->port[lcnt].dsp_lock);
415 }
416 atomic_set(&ac->cmd_state, 0);
417
418 pr_debug("%s: session[%d]\n", __func__, ac->session);
419
420 return ac;
421fail:
422 q6asm_audio_client_free(ac);
423 return NULL;
424fail_session:
425 kfree(ac);
426 return NULL;
427}
428
429int q6asm_audio_client_buf_alloc(unsigned int dir,
430 struct audio_client *ac,
431 unsigned int bufsz,
432 unsigned int bufcnt)
433{
434 int cnt = 0;
435 int rc = 0;
436 struct audio_buffer *buf;
437
438 if (!(ac) || ((dir != IN) && (dir != OUT)))
439 return -EINVAL;
440
441 pr_debug("%s: session[%d]bufsz[%d]bufcnt[%d]\n", __func__, ac->session,
442 bufsz, bufcnt);
443
444 if (ac->session <= 0 || ac->session > 8)
445 goto fail;
446
447 if (ac->io_mode == SYNC_IO_MODE) {
448 if (ac->port[dir].buf) {
449 pr_debug("%s: buffer already allocated\n", __func__);
450 return 0;
451 }
452 mutex_lock(&ac->cmd_lock);
453 buf = kzalloc(((sizeof(struct audio_buffer))*bufcnt),
454 GFP_KERNEL);
455
456 if (!buf) {
457 mutex_unlock(&ac->cmd_lock);
458 goto fail;
459 }
460
461 ac->port[dir].buf = buf;
462
463 while (cnt < bufcnt) {
464 if (bufsz > 0) {
465 if (!buf[cnt].data) {
466 unsigned int flags = 0;
467 buf[cnt].phys =
468 allocate_contiguous_ebi_nomap(bufsz,
469 SZ_4K);
470 if (!buf[cnt].phys) {
471 pr_err("%s:Buf alloc failed "
472 " size=%d\n", __func__,
473 bufsz);
474 mutex_unlock(&ac->cmd_lock);
475 goto fail;
476 }
477 flags = MSM_SUBSYSTEM_MAP_KADDR |
478 MSM_SUBSYSTEM_MAP_CACHED;
479 buf[cnt].mem_buffer =
480 msm_subsystem_map_buffer(buf[cnt].phys,
481 bufsz, flags, NULL, 0);
482 if (IS_ERR(
483 (void *)buf[cnt].mem_buffer)) {
484 pr_err("%s:map_buffer failed,"
485 "error = %ld\n",
486 __func__, PTR_ERR((void *)buf[cnt].mem_buffer));
487 goto fail;
488 }
489 buf[cnt].data =
490 buf[cnt].mem_buffer->vaddr;
491 if (!buf[cnt].data) {
492 pr_err("%s:invalid vaddr,"
493 " iomap failed\n", __func__);
494 goto fail;
495 }
496 buf[cnt].used = 1;
497 buf[cnt].size = bufsz;
498 buf[cnt].actual_size = bufsz;
499 pr_debug("%s data[%p]phys[%p][%p]"
500 "mem_buffer[%p]\n",
501 __func__,
502 (void *)buf[cnt].data,
503 (void *)buf[cnt].phys,
504 (void *)&buf[cnt].phys,
505 (void *)buf[cnt].mem_buffer);
506 cnt++;
507 }
508 }
509 }
510 ac->port[dir].max_buf_cnt = cnt;
511
512 mutex_unlock(&ac->cmd_lock);
513 rc = q6asm_memory_map_regions(ac, dir, bufsz, cnt);
514 if (rc < 0) {
515 pr_err("%s:CMD Memory_map_regions failed\n", __func__);
516 goto fail;
517 }
518 }
519 return 0;
520fail:
521 q6asm_audio_client_buf_free(dir, ac);
522 return -EINVAL;
523}
524
525int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir,
526 struct audio_client *ac,
527 unsigned int bufsz,
528 unsigned int bufcnt)
529{
530 int cnt = 0;
531 int rc = 0;
532 struct audio_buffer *buf;
533
534 if (!(ac) || ((dir != IN) && (dir != OUT)))
535 return -EINVAL;
536
537 pr_debug("%s: session[%d]bufsz[%d]bufcnt[%d]\n",
538 __func__, ac->session,
539 bufsz, bufcnt);
540
541 if (ac->session <= 0 || ac->session > 8)
542 goto fail;
543
544 if (ac->port[dir].buf) {
545 pr_debug("%s: buffer already allocated\n", __func__);
546 return 0;
547 }
548 mutex_lock(&ac->cmd_lock);
549 buf = kzalloc(((sizeof(struct audio_buffer))*bufcnt),
550 GFP_KERNEL);
551
552 if (!buf) {
553 mutex_unlock(&ac->cmd_lock);
554 goto fail;
555 }
556
557 ac->port[dir].buf = buf;
558
559 buf[0].data = dma_alloc_coherent(NULL, bufsz * bufcnt,
560 &buf[0].phys, GFP_KERNEL);
561 buf[0].used = dir ^ 1;
562 buf[0].size = bufsz;
563 buf[0].actual_size = bufsz;
564 cnt = 1;
565 while (cnt < bufcnt) {
566 if (bufsz > 0) {
567 buf[cnt].data = buf[0].data + (cnt * bufsz);
568 buf[cnt].phys = buf[0].phys + (cnt * bufsz);
569 if (!buf[cnt].data) {
570 pr_err("%s Buf alloc failed\n",
571 __func__);
572 mutex_unlock(&ac->cmd_lock);
573 goto fail;
574 }
575 buf[cnt].used = dir ^ 1;
576 buf[cnt].size = bufsz;
577 buf[cnt].actual_size = bufsz;
578 pr_debug("%s data[%p]phys[%p][%p]\n", __func__,
579 (void *)buf[cnt].data,
580 (void *)buf[cnt].phys,
581 (void *)&buf[cnt].phys);
582 }
583 cnt++;
584 }
585 ac->port[dir].max_buf_cnt = cnt;
586 mutex_unlock(&ac->cmd_lock);
587 rc = q6asm_memory_map(ac, buf[0].phys, dir, bufsz, cnt);
588 if (rc < 0) {
589 pr_err("%s:CMD Memory_map_regions failed\n", __func__);
590 goto fail;
591 }
592 return 0;
593fail:
594 q6asm_audio_client_buf_free_contiguous(dir, ac);
595 return -EINVAL;
596}
597
598static int32_t q6asm_mmapcallback(struct apr_client_data *data, void *priv)
599{
600 uint32_t token;
601 uint32_t *payload = data->payload;
602
603 if (data->opcode == RESET_EVENTS) {
604 pr_debug("%s: Reset event is received: %d %d apr[%p]\n",
605 __func__,
606 data->reset_event,
607 data->reset_proc,
608 this_mmap.apr);
609 apr_reset(this_mmap.apr);
610 this_mmap.apr = NULL;
611 atomic_set(&this_mmap.cmd_state, 0);
612 return 0;
613 }
614
615 pr_debug("%s:ptr0[0x%x]ptr1[0x%x]opcode[0x%x]"
616 "token[0x%x]payload_s[%d] src[%d] dest[%d]\n", __func__,
617 payload[0], payload[1], data->opcode, data->token,
618 data->payload_size, data->src_port, data->dest_port);
619
620 if (data->opcode == APR_BASIC_RSP_RESULT) {
621 token = data->token;
622 switch (payload[0]) {
623 case ASM_SESSION_CMD_MEMORY_MAP:
624 case ASM_SESSION_CMD_MEMORY_UNMAP:
625 case ASM_SESSION_CMD_MEMORY_MAP_REGIONS:
626 case ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS:
627 pr_debug("%s:command[0x%x]success [0x%x]\n",
628 __func__, payload[0], payload[1]);
629 if (atomic_read(&this_mmap.cmd_state)) {
630 atomic_set(&this_mmap.cmd_state, 0);
631 wake_up(&this_mmap.cmd_wait);
632 }
633 break;
634 default:
635 pr_debug("%s:command[0x%x] not expecting rsp\n",
636 __func__, payload[0]);
637 break;
638 }
639 }
640 return 0;
641}
642
643
644static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
645{
646 int i = 0;
647 struct audio_client *ac = (struct audio_client *)priv;
648 uint32_t token;
649 unsigned long dsp_flags;
650 uint32_t *payload;
651
652
653 if ((ac == NULL) || (data == NULL)) {
654 pr_err("ac or priv NULL\n");
655 return -EINVAL;
656 }
657 if (ac->session <= 0 || ac->session > 8) {
658 pr_err("%s:Session ID is invalid, session = %d\n", __func__,
659 ac->session);
660 return -EINVAL;
661 }
662
663 payload = data->payload;
664
665 if (data->opcode == RESET_EVENTS) {
666 pr_debug("q6asm_callback: Reset event is received: %d %d apr[%p]\n",
667 data->reset_event, data->reset_proc, ac->apr);
668 apr_reset(ac->apr);
669 return 0;
670 }
671
672 pr_debug("%s: session[%d]opcode[0x%x] \
673 token[0x%x]payload_s[%d] src[%d] dest[%d]\n", __func__,
674 ac->session, data->opcode,
675 data->token, data->payload_size, data->src_port,
676 data->dest_port);
677
678 if (data->opcode == APR_BASIC_RSP_RESULT) {
679 token = data->token;
680 switch (payload[0]) {
681 case ASM_STREAM_CMD_SET_PP_PARAMS:
682#ifdef CONFIG_MSM8X60_RTAC
683 if (rtac_make_asm_callback(ac->session, payload,
684 data->payload_size))
685 break;
686#endif
687 case ASM_SESSION_CMD_PAUSE:
688 case ASM_DATA_CMD_EOS:
689 case ASM_STREAM_CMD_CLOSE:
690 case ASM_STREAM_CMD_FLUSH:
691 case ASM_SESSION_CMD_RUN:
692 case ASM_SESSION_CMD_REGISTER_FOR_TX_OVERFLOW_EVENTS:
693 case ASM_STREAM_CMD_FLUSH_READBUFS:
694 pr_debug("%s:Payload = [0x%x]\n", __func__, payload[0]);
695 if (token != ac->session) {
696 pr_err("%s:Invalid session[%d] rxed expected[%d]",
697 __func__, token, ac->session);
698 return -EINVAL;
699 }
700 case ASM_STREAM_CMD_OPEN_READ:
701 case ASM_STREAM_CMD_OPEN_WRITE:
702 case ASM_STREAM_CMD_OPEN_READWRITE:
703 case ASM_DATA_CMD_MEDIA_FORMAT_UPDATE:
704 case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
705 if (atomic_read(&ac->cmd_state)) {
706 atomic_set(&ac->cmd_state, 0);
707 wake_up(&ac->cmd_wait);
708 }
709 if (ac->cb)
710 ac->cb(data->opcode, data->token,
711 (uint32_t *)data->payload, ac->priv);
712 break;
713 default:
714 pr_debug("%s:command[0x%x] not expecting rsp\n",
715 __func__, payload[0]);
716 break;
717 }
718 return 0;
719 }
720
721 switch (data->opcode) {
722 case ASM_DATA_EVENT_WRITE_DONE:{
723 struct audio_port_data *port = &ac->port[IN];
724 pr_debug("%s: Rxed opcode[0x%x] status[0x%x] token[%d]",
725 __func__, payload[0], payload[1],
726 data->token);
727 if (ac->io_mode == SYNC_IO_MODE) {
728 if (port->buf == NULL) {
729 pr_err("%s: Unexpected Write Done\n",
730 __func__);
731 return -EINVAL;
732 }
733 spin_lock_irqsave(&port->dsp_lock, dsp_flags);
734 if (port->buf[data->token].phys !=
735 payload[0]) {
736 pr_err("Buf expected[%p]rxed[%p]\n",\
737 (void *)port->buf[data->token].phys,\
738 (void *)payload[0]);
739 spin_unlock_irqrestore(&port->dsp_lock,
740 dsp_flags);
741 return -EINVAL;
742 }
743 token = data->token;
744 port->buf[token].used = 1;
745 spin_unlock_irqrestore(&port->dsp_lock, dsp_flags);
Rajesha Kini3498c932011-07-19 19:58:27 +0530746#ifdef CONFIG_DEBUG_FS
747 if (out_enable_flag) {
748 /* For first Write done log the time and reset
749 out_cold_index*/
750 if (out_cold_index != 1) {
751 do_gettimeofday(&out_cold_tv);
752 pr_debug("COLD: apr_send_pkt at %ld \
753 sec %ld microsec\n",\
754 out_cold_tv.tv_sec,\
755 out_cold_tv.tv_usec);
756 out_cold_index = 1;
757 }
758 pr_debug("out_enable_flag %ld",\
759 out_enable_flag);
760 }
761#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700762 for (i = 0; i < port->max_buf_cnt; i++)
763 pr_debug("%d ", port->buf[i].used);
764
765 }
766 break;
767 }
768#ifdef CONFIG_MSM8X60_RTAC
769 case ASM_STREAM_CMDRSP_GET_PP_PARAMS:
770 rtac_make_asm_callback(ac->session, payload,
771 data->payload_size);
772 break;
773#endif
774 case ASM_DATA_EVENT_READ_DONE:{
775
776 struct audio_port_data *port = &ac->port[OUT];
Rajesha Kini3498c932011-07-19 19:58:27 +0530777#ifdef CONFIG_DEBUG_FS
778 if (in_enable_flag) {
779 /* when in_cont_index == 7, DSP would be
780 * writing into the 8th 512 byte buffer and this
781 * timestamp is tapped here.Once done it then writes
782 * to 9th 512 byte buffer.These two buffers(8th, 9th)
783 * reach the test application in 5th iteration and that
784 * timestamp is tapped at user level. The difference
785 * of these two timestamps gives us the time between
786 * the time at which dsp started filling the sample
787 * required and when it reached the test application.
788 * Hence continuous input latency
789 */
790 if (in_cont_index == 7) {
791 do_gettimeofday(&in_cont_tv);
792 pr_err("In_CONT:previous read buffer done \
793 at %ld sec %ld microsec\n",\
794 out_cont_tv.tv_sec, out_cont_tv.tv_usec);
795 }
796 }
797#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700798 pr_debug("%s:R-D: status=%d buff_add=%x act_size=%d offset=%d\n",
799 __func__, payload[READDONE_IDX_STATUS],
800 payload[READDONE_IDX_BUFFER],
801 payload[READDONE_IDX_SIZE],
802 payload[READDONE_IDX_OFFSET]);
803 pr_debug("%s:R-D:msw_ts=%d lsw_ts=%d flags=%d id=%d num=%d\n",
804 __func__, payload[READDONE_IDX_MSW_TS],
805 payload[READDONE_IDX_LSW_TS],
806 payload[READDONE_IDX_FLAGS],
807 payload[READDONE_IDX_ID],
808 payload[READDONE_IDX_NUMFRAMES]);
Rajesha Kini3498c932011-07-19 19:58:27 +0530809#ifdef CONFIG_DEBUG_FS
810 if (in_enable_flag) {
811 in_cont_index++;
812 }
813#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700814 if (ac->io_mode == SYNC_IO_MODE) {
815 if (port->buf == NULL) {
816 pr_err("%s: Unexpected Write Done\n", __func__);
817 return -EINVAL;
818 }
819 spin_lock_irqsave(&port->dsp_lock, dsp_flags);
820 token = data->token;
821 port->buf[token].used = 0;
822 if (port->buf[token].phys !=
823 payload[READDONE_IDX_BUFFER]) {
824 pr_err("Buf expected[%p]rxed[%p]\n",\
825 (void *)port->buf[token].phys,\
826 (void *)payload[READDONE_IDX_BUFFER]);
827 spin_unlock_irqrestore(&port->dsp_lock,
828 dsp_flags);
829 break;
830 }
831 port->buf[token].actual_size =
832 payload[READDONE_IDX_SIZE];
833 spin_unlock_irqrestore(&port->dsp_lock, dsp_flags);
834 }
835 break;
836 }
837 case ASM_DATA_EVENT_EOS:
838 case ASM_DATA_CMDRSP_EOS:
839 pr_debug("%s:EOS ACK received: rxed opcode[0x%x]\n",
840 __func__, data->opcode);
841 break;
842 case ASM_STREAM_CMDRSP_GET_ENCDEC_PARAM:
843 break;
844 case ASM_SESSION_EVENT_TX_OVERFLOW:
845 pr_err("ASM_SESSION_EVENT_TX_OVERFLOW\n");
846 break;
847 case ASM_SESSION_CMDRSP_GET_SESSION_TIME:
848 pr_debug("%s: ASM_SESSION_CMDRSP_GET_SESSION_TIME, "
849 "payload[0] = %d, payload[1] = %d, "
850 "payload[2] = %d\n", __func__,
851 payload[0], payload[1], payload[2]);
852 ac->time_stamp = (uint64_t)(((uint64_t)payload[1] << 32) |
853 payload[2]);
854 if (atomic_read(&ac->time_flag)) {
855 atomic_set(&ac->time_flag, 0);
856 wake_up(&ac->time_wait);
857 }
858 break;
859 case ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY:
860 pr_debug("%s: ASM_DATA_EVENT_SR_CM_CHANGE_NOTIFY, "
861 "payload[0] = %d, payload[1] = %d, "
862 "payload[2] = %d, payload[3] = %d\n", __func__,
863 payload[0], payload[1], payload[2],
864 payload[3]);
865 break;
866 }
867 if (ac->cb)
868 ac->cb(data->opcode, data->token,
869 data->payload, ac->priv);
870
871 return 0;
872}
873
874void *q6asm_is_cpu_buf_avail(int dir, struct audio_client *ac, uint32_t *size,
875 uint32_t *index)
876{
877 void *data;
878 unsigned char idx;
879 struct audio_port_data *port;
880
881 if (!ac || ((dir != IN) && (dir != OUT)))
882 return NULL;
883
884 if (ac->io_mode == SYNC_IO_MODE) {
885 port = &ac->port[dir];
886
887 mutex_lock(&port->lock);
888 idx = port->cpu_buf;
889 if (port->buf == NULL) {
890 pr_debug("%s:Buffer pointer null\n", __func__);
891 return NULL;
892 }
893 /* dir 0: used = 0 means buf in use
894 dir 1: used = 1 means buf in use */
895 if (port->buf[idx].used == dir) {
896 /* To make it more robust, we could loop and get the
897 next avail buf, its risky though */
898 pr_debug("%s:Next buf idx[0x%x] not available,\
899 dir[%d]\n", __func__, idx, dir);
900 mutex_unlock(&port->lock);
901 return NULL;
902 }
903 *size = port->buf[idx].actual_size;
904 *index = port->cpu_buf;
905 data = port->buf[idx].data;
906 pr_debug("%s:session[%d]index[%d] data[%p]size[%d]\n",
907 __func__,
908 ac->session,
909 port->cpu_buf,
910 data, *size);
911 /* By default increase the cpu_buf cnt
912 user accesses this function,increase cpu
913 buf(to avoid another api)*/
914 port->buf[idx].used = dir;
915 port->cpu_buf = ((port->cpu_buf + 1) & (port->max_buf_cnt - 1));
916 mutex_unlock(&port->lock);
917 return data;
918 }
919 return NULL;
920}
921
Jay Wang9cf59a02011-08-10 16:58:40 -0700922void *q6asm_is_cpu_buf_avail_nolock(int dir, struct audio_client *ac,
923 uint32_t *size, uint32_t *index)
924{
925 void *data;
926 unsigned char idx;
927 struct audio_port_data *port;
928
929 if (!ac || ((dir != IN) && (dir != OUT)))
930 return NULL;
931
932 port = &ac->port[dir];
933
934 idx = port->cpu_buf;
935 if (port->buf == NULL) {
936 pr_debug("%s:Buffer pointer null\n", __func__);
937 return NULL;
938 }
939 /*
940 * dir 0: used = 0 means buf in use
941 * dir 1: used = 1 means buf in use
942 */
943 if (port->buf[idx].used == dir) {
944 /*
945 * To make it more robust, we could loop and get the
946 * next avail buf, its risky though
947 */
948 pr_debug("%s:Next buf idx[0x%x] not available,\
949 dir[%d]\n", __func__, idx, dir);
950 return NULL;
951 }
952 *size = port->buf[idx].actual_size;
953 *index = port->cpu_buf;
954 data = port->buf[idx].data;
955 pr_debug("%s:session[%d]index[%d] data[%p]size[%d]\n",
956 __func__, ac->session, port->cpu_buf,
957 data, *size);
958 /*
959 * By default increase the cpu_buf cnt
960 * user accesses this function,increase cpu
961 * buf(to avoid another api)
962 */
963 port->buf[idx].used = dir;
964 port->cpu_buf = ((port->cpu_buf + 1) & (port->max_buf_cnt - 1));
965 return data;
966}
967
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700968int q6asm_is_dsp_buf_avail(int dir, struct audio_client *ac)
969{
970 int ret = -1;
971 struct audio_port_data *port;
972 uint32_t idx;
973
974 if (!ac || (dir != OUT))
975 return ret;
976
977 if (ac->io_mode == SYNC_IO_MODE) {
978 port = &ac->port[dir];
979
980 mutex_lock(&port->lock);
981 idx = port->dsp_buf;
982
983 if (port->buf[idx].used == (dir ^ 1)) {
984 /* To make it more robust, we could loop and get the
985 next avail buf, its risky though */
986 pr_err("Next buf idx[0x%x] not available, dir[%d]\n",
987 idx, dir);
988 mutex_unlock(&port->lock);
989 return ret;
990 }
991 pr_debug("%s: session[%d]dsp_buf=%d cpu_buf=%d\n", __func__,
992 ac->session, port->dsp_buf, port->cpu_buf);
993 ret = ((port->dsp_buf != port->cpu_buf) ? 0 : -1);
994 mutex_unlock(&port->lock);
995 }
996 return ret;
997}
998
999static void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
1000 uint32_t pkt_size, uint32_t cmd_flg)
1001{
1002 pr_debug("%s:session=%d pkt size=%d cmd_flg=%d\n", __func__, pkt_size,
1003 cmd_flg, ac->session);
1004 mutex_lock(&ac->cmd_lock);
1005 hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
1006 APR_HDR_LEN(sizeof(struct apr_hdr)),\
1007 APR_PKT_VER);
1008 hdr->src_svc = ((struct apr_svc *)ac->apr)->id;
1009 hdr->src_domain = APR_DOMAIN_APPS;
1010 hdr->dest_svc = APR_SVC_ASM;
1011 hdr->dest_domain = APR_DOMAIN_ADSP;
1012 hdr->src_port = ((ac->session << 8) & 0xFF00) | 0x01;
1013 hdr->dest_port = ((ac->session << 8) & 0xFF00) | 0x01;
1014 if (cmd_flg) {
1015 hdr->token = ac->session;
1016 atomic_set(&ac->cmd_state, 1);
1017 }
1018 hdr->pkt_size = pkt_size;
1019 mutex_unlock(&ac->cmd_lock);
1020 return;
1021}
1022
1023static void q6asm_add_mmaphdr(struct apr_hdr *hdr, uint32_t pkt_size,
1024 uint32_t cmd_flg)
1025{
1026 pr_debug("%s:pkt size=%d cmd_flg=%d\n", __func__, pkt_size, cmd_flg);
1027 hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
1028 APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
1029 hdr->src_port = 0;
1030 hdr->dest_port = 0;
1031 if (cmd_flg) {
1032 hdr->token = 0;
1033 atomic_set(&this_mmap.cmd_state, 1);
1034 }
1035 hdr->pkt_size = pkt_size;
1036 return;
1037}
1038
1039int q6asm_open_read(struct audio_client *ac,
1040 uint32_t format)
1041{
1042 int rc = 0x00;
1043 struct asm_stream_cmd_open_read open;
Rajesha Kini3498c932011-07-19 19:58:27 +05301044#ifdef CONFIG_DEBUG_FS
1045 in_cont_index = 0;
1046#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001047 if ((ac == NULL) || (ac->apr == NULL)) {
1048 pr_err("%s: APR handle NULL\n", __func__);
1049 return -EINVAL;
1050 }
1051 pr_debug("%s:session[%d]", __func__, ac->session);
1052
1053 q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
1054 open.hdr.opcode = ASM_STREAM_CMD_OPEN_READ;
1055 /* Stream prio : High, provide meta info with encoded frames */
1056 open.src_endpoint = ASM_END_POINT_DEVICE_MATRIX;
1057
1058 open.pre_proc_top = get_asm_topology();
1059 if (open.pre_proc_top == 0)
1060 open.pre_proc_top = DEFAULT_POPP_TOPOLOGY;
1061
1062 switch (format) {
1063 case FORMAT_LINEAR_PCM:
1064 open.uMode = STREAM_PRIORITY_HIGH;
1065 open.format = LINEAR_PCM;
1066 break;
1067 case FORMAT_MPEG4_AAC:
1068 open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
1069 open.format = MPEG4_AAC;
1070 break;
1071 case FORMAT_V13K:
1072 open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
1073 open.format = V13K_FS;
1074 break;
1075 case FORMAT_EVRC:
1076 open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
1077 open.format = EVRC_FS;
1078 break;
1079 case FORMAT_AMRNB:
1080 open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_HIGH;
1081 open.format = AMRNB_FS;
1082 break;
1083 default:
1084 pr_err("Invalid format[%d]\n", format);
1085 goto fail_cmd;
1086 }
1087 rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
1088 if (rc < 0) {
1089 pr_err("open failed op[0x%x]rc[%d]\n", \
1090 open.hdr.opcode, rc);
1091 goto fail_cmd;
1092 }
1093 rc = wait_event_timeout(ac->cmd_wait,
1094 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1095 if (!rc) {
1096 pr_err("%s: timeout. waited for OPEN_WRITE rc[%d]\n", __func__,
1097 rc);
1098 goto fail_cmd;
1099 }
1100 return 0;
1101fail_cmd:
1102 return -EINVAL;
1103}
1104
1105int q6asm_open_write(struct audio_client *ac, uint32_t format)
1106{
1107 int rc = 0x00;
1108 struct asm_stream_cmd_open_write open;
1109
1110 if ((ac == NULL) || (ac->apr == NULL)) {
1111 pr_err("%s: APR handle NULL\n", __func__);
1112 return -EINVAL;
1113 }
1114 pr_debug("%s: session[%d] wr_format[0x%x]", __func__, ac->session,
1115 format);
1116
1117 q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
1118
1119 open.hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE;
1120 open.uMode = STREAM_PRIORITY_HIGH;
1121 /* source endpoint : matrix */
1122 open.sink_endpoint = ASM_END_POINT_DEVICE_MATRIX;
1123 open.stream_handle = 0x00;
1124
1125 open.post_proc_top = get_asm_topology();
1126 if (open.post_proc_top == 0)
1127 open.post_proc_top = DEFAULT_POPP_TOPOLOGY;
1128
1129 switch (format) {
1130 case FORMAT_LINEAR_PCM:
1131 open.format = LINEAR_PCM;
1132 break;
1133 case FORMAT_MPEG4_AAC:
1134 open.format = MPEG4_AAC;
1135 break;
1136 case FORMAT_WMA_V9:
1137 open.format = WMA_V9;
1138 break;
1139 case FORMAT_WMA_V10PRO:
1140 open.format = WMA_V10PRO;
1141 break;
1142 default:
1143 pr_err("%s: Invalid format[%d]\n", __func__, format);
1144 goto fail_cmd;
1145 }
1146 rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
1147 if (rc < 0) {
1148 pr_err("%s: open failed op[0x%x]rc[%d]\n", \
1149 __func__, open.hdr.opcode, rc);
1150 goto fail_cmd;
1151 }
1152 rc = wait_event_timeout(ac->cmd_wait,
1153 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1154 if (!rc) {
1155 pr_err("%s: timeout. waited for OPEN_WRITE rc[%d]\n", __func__,
1156 rc);
1157 goto fail_cmd;
1158 }
1159 return 0;
1160fail_cmd:
1161 return -EINVAL;
1162}
1163
1164int q6asm_open_read_write(struct audio_client *ac,
1165 uint32_t rd_format,
1166 uint32_t wr_format)
1167{
1168 int rc = 0x00;
1169 struct asm_stream_cmd_open_read_write open;
1170
1171 if ((ac == NULL) || (ac->apr == NULL)) {
1172 pr_err("APR handle NULL\n");
1173 return -EINVAL;
1174 }
1175 pr_debug("%s: session[%d]", __func__, ac->session);
1176 pr_debug("wr_format[0x%x]rd_format[0x%x]",
1177 wr_format, rd_format);
1178
1179 q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
1180 open.hdr.opcode = ASM_STREAM_CMD_OPEN_READWRITE;
1181
1182 open.uMode = BUFFER_META_ENABLE | STREAM_PRIORITY_NORMAL |
1183 SR_CM_NOTIFY_ENABLE;
1184 /* source endpoint : matrix */
1185 open.post_proc_top = get_asm_topology();
1186 if (open.post_proc_top == 0)
1187 open.post_proc_top = DEFAULT_POPP_TOPOLOGY;
1188
1189 switch (wr_format) {
1190 case FORMAT_LINEAR_PCM:
1191 open.write_format = LINEAR_PCM;
1192 break;
1193 case FORMAT_MPEG4_AAC:
1194 open.write_format = MPEG4_AAC;
1195 break;
1196 case FORMAT_WMA_V9:
1197 open.write_format = WMA_V9;
1198 break;
1199 case FORMAT_WMA_V10PRO:
1200 open.write_format = WMA_V10PRO;
1201 break;
1202 default:
1203 pr_err("Invalid format[%d]\n", wr_format);
1204 goto fail_cmd;
1205 }
1206
1207 switch (rd_format) {
1208 case FORMAT_LINEAR_PCM:
1209 open.read_format = LINEAR_PCM;
1210 break;
1211 case FORMAT_MPEG4_AAC:
1212 open.read_format = MPEG4_AAC;
1213 break;
1214 case FORMAT_V13K:
1215 open.read_format = V13K_FS;
1216 break;
1217 case FORMAT_EVRC:
1218 open.read_format = EVRC_FS;
1219 break;
1220 case FORMAT_AMRNB:
1221 open.read_format = AMRNB_FS;
1222 break;
1223 default:
1224 pr_err("Invalid format[%d]\n", rd_format);
1225 goto fail_cmd;
1226 }
1227 pr_debug("%s:rdformat[0x%x]wrformat[0x%x]\n", __func__,
1228 open.read_format, open.write_format);
1229
1230 rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
1231 if (rc < 0) {
1232 pr_err("open failed op[0x%x]rc[%d]\n", \
1233 open.hdr.opcode, rc);
1234 goto fail_cmd;
1235 }
1236 rc = wait_event_timeout(ac->cmd_wait,
1237 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1238 if (!rc) {
1239 pr_err("timeout. waited for OPEN_WRITE rc[%d]\n", rc);
1240 goto fail_cmd;
1241 }
1242 return 0;
1243fail_cmd:
1244 return -EINVAL;
1245}
1246
1247int q6asm_run(struct audio_client *ac, uint32_t flags,
1248 uint32_t msw_ts, uint32_t lsw_ts)
1249{
1250 struct asm_stream_cmd_run run;
1251 int rc;
1252 if (!ac || ac->apr == NULL) {
1253 pr_err("APR handle NULL\n");
1254 return -EINVAL;
1255 }
1256 pr_debug("%s session[%d]", __func__, ac->session);
1257 q6asm_add_hdr(ac, &run.hdr, sizeof(run), TRUE);
1258
1259 run.hdr.opcode = ASM_SESSION_CMD_RUN;
1260 run.flags = flags;
1261 run.msw_ts = msw_ts;
1262 run.lsw_ts = lsw_ts;
Rajesha Kini3498c932011-07-19 19:58:27 +05301263#ifdef CONFIG_DEBUG_FS
1264 if (out_enable_flag) {
1265 do_gettimeofday(&out_cold_tv);
1266 pr_debug("COLD: apr_send_pkt at %ld sec %ld microsec\n",\
1267 out_cold_tv.tv_sec, out_cold_tv.tv_usec);
1268 }
1269#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001270 rc = apr_send_pkt(ac->apr, (uint32_t *) &run);
1271 if (rc < 0) {
1272 pr_err("Commmand run failed[%d]", rc);
1273 goto fail_cmd;
1274 }
1275
1276 rc = wait_event_timeout(ac->cmd_wait,
1277 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1278 if (!rc) {
1279 pr_err("timeout. waited for run success rc[%d]", rc);
1280 goto fail_cmd;
1281 }
1282
1283 return 0;
1284fail_cmd:
1285 return -EINVAL;
1286}
1287
1288int q6asm_run_nowait(struct audio_client *ac, uint32_t flags,
1289 uint32_t msw_ts, uint32_t lsw_ts)
1290{
1291 struct asm_stream_cmd_run run;
1292 int rc;
1293 if (!ac || ac->apr == NULL) {
1294 pr_err("%s:APR handle NULL\n", __func__);
1295 return -EINVAL;
1296 }
1297 pr_debug("session[%d]", ac->session);
1298 q6asm_add_hdr_async(ac, &run.hdr, sizeof(run), TRUE);
1299
1300 run.hdr.opcode = ASM_SESSION_CMD_RUN;
1301 run.flags = flags;
1302 run.msw_ts = msw_ts;
1303 run.lsw_ts = lsw_ts;
1304
1305 rc = apr_send_pkt(ac->apr, (uint32_t *) &run);
1306 if (rc < 0) {
1307 pr_err("%s:Commmand run failed[%d]", __func__, rc);
1308 return -EINVAL;
1309 }
1310 return 0;
1311}
1312
1313
1314int q6asm_enc_cfg_blk_aac(struct audio_client *ac,
1315 uint32_t frames_per_buf,
1316 uint32_t sample_rate, uint32_t channels,
1317 uint32_t bit_rate, uint32_t mode, uint32_t format)
1318{
1319 struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
1320 int rc = 0;
1321
1322 pr_debug("%s:session[%d]frames[%d]SR[%d]ch[%d]bitrate[%d]mode[%d]"
1323 "format[%d]", __func__, ac->session, frames_per_buf,
1324 sample_rate, channels, bit_rate, mode, format);
1325
1326 q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
1327
1328 enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
1329 enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
1330 enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
1331 enc_cfg.enc_blk.frames_per_buf = frames_per_buf;
1332 enc_cfg.enc_blk.format_id = MPEG4_AAC;
1333 enc_cfg.enc_blk.cfg_size = sizeof(struct asm_aac_read_cfg);
1334 enc_cfg.enc_blk.cfg.aac.bitrate = bit_rate;
1335 enc_cfg.enc_blk.cfg.aac.enc_mode = mode;
1336 enc_cfg.enc_blk.cfg.aac.format = format;
1337 enc_cfg.enc_blk.cfg.aac.ch_cfg = channels;
1338 enc_cfg.enc_blk.cfg.aac.sample_rate = sample_rate;
1339
1340 rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
1341 if (rc < 0) {
1342 pr_err("Comamnd %d failed\n", ASM_STREAM_CMD_SET_ENCDEC_PARAM);
1343 rc = -EINVAL;
1344 goto fail_cmd;
1345 }
1346 rc = wait_event_timeout(ac->cmd_wait,
1347 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1348 if (!rc) {
1349 pr_err("timeout. waited for FORMAT_UPDATE\n");
1350 goto fail_cmd;
1351 }
1352 return 0;
1353fail_cmd:
1354 return -EINVAL;
1355}
1356
1357int q6asm_enc_cfg_blk_pcm(struct audio_client *ac,
1358 uint32_t rate, uint32_t channels)
1359{
1360 struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
1361
1362 int rc = 0;
1363
1364 pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__,
1365 ac->session, rate, channels);
1366
1367 q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
1368
1369 enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
1370 enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
1371 enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
1372 enc_cfg.enc_blk.frames_per_buf = 1;
1373 enc_cfg.enc_blk.format_id = LINEAR_PCM;
1374 enc_cfg.enc_blk.cfg_size = sizeof(struct asm_pcm_cfg);
1375 enc_cfg.enc_blk.cfg.pcm.ch_cfg = channels;
1376 enc_cfg.enc_blk.cfg.pcm.bits_per_sample = 16;
1377 enc_cfg.enc_blk.cfg.pcm.sample_rate = rate;
1378 enc_cfg.enc_blk.cfg.pcm.is_signed = 1;
1379 enc_cfg.enc_blk.cfg.pcm.interleaved = 1;
1380
1381 rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
1382 if (rc < 0) {
1383 pr_err("Comamnd open failed\n");
1384 rc = -EINVAL;
1385 goto fail_cmd;
1386 }
1387 rc = wait_event_timeout(ac->cmd_wait,
1388 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1389 if (!rc) {
1390 pr_err("timeout opcode[0x%x] ", enc_cfg.hdr.opcode);
1391 goto fail_cmd;
1392 }
1393 return 0;
1394fail_cmd:
1395 return -EINVAL;
1396}
1397
1398int q6asm_enable_sbrps(struct audio_client *ac,
1399 uint32_t sbr_ps_enable)
1400{
1401 struct asm_stream_cmd_encdec_sbr sbrps;
1402
1403 int rc = 0;
1404
1405 pr_debug("%s: Session %d\n", __func__, ac->session);
1406
1407 q6asm_add_hdr(ac, &sbrps.hdr, sizeof(sbrps), TRUE);
1408
1409 sbrps.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
1410 sbrps.param_id = ASM_ENABLE_SBR_PS;
1411 sbrps.param_size = sizeof(struct asm_sbr_ps);
1412 sbrps.sbr_ps.enable = sbr_ps_enable;
1413
1414 rc = apr_send_pkt(ac->apr, (uint32_t *) &sbrps);
1415 if (rc < 0) {
1416 pr_err("Command opcode[0x%x]paramid[0x%x] failed\n",
1417 ASM_STREAM_CMD_SET_ENCDEC_PARAM,
1418 ASM_ENABLE_SBR_PS);
1419 rc = -EINVAL;
1420 goto fail_cmd;
1421 }
1422 rc = wait_event_timeout(ac->cmd_wait,
1423 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1424 if (!rc) {
1425 pr_err("timeout opcode[0x%x] ", sbrps.hdr.opcode);
1426 goto fail_cmd;
1427 }
1428 return 0;
1429fail_cmd:
1430 return -EINVAL;
1431}
1432
Swaminathan Sathappan70765cd2011-07-19 18:42:47 -07001433int q6asm_cfg_dual_mono_aac(struct audio_client *ac,
1434 uint16_t sce_left, uint16_t sce_right)
1435{
1436 struct asm_stream_cmd_encdec_dualmono dual_mono;
1437
1438 int rc = 0;
1439
1440 pr_debug("%s: Session %d, sce_left = %d, sce_right = %d\n",
1441 __func__, ac->session, sce_left, sce_right);
1442
1443 q6asm_add_hdr(ac, &dual_mono.hdr, sizeof(dual_mono), TRUE);
1444
1445 dual_mono.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
1446 dual_mono.param_id = ASM_CONFIGURE_DUAL_MONO;
1447 dual_mono.param_size = sizeof(struct asm_dual_mono);
1448 dual_mono.channel_map.sce_left = sce_left;
1449 dual_mono.channel_map.sce_right = sce_right;
1450
1451 rc = apr_send_pkt(ac->apr, (uint32_t *) &dual_mono);
1452 if (rc < 0) {
1453 pr_err("%s:Command opcode[0x%x]paramid[0x%x] failed\n",
1454 __func__, ASM_STREAM_CMD_SET_ENCDEC_PARAM,
1455 ASM_CONFIGURE_DUAL_MONO);
1456 rc = -EINVAL;
1457 goto fail_cmd;
1458 }
1459 rc = wait_event_timeout(ac->cmd_wait,
1460 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1461 if (!rc) {
1462 pr_err("%s:timeout opcode[0x%x]\n", __func__,
1463 dual_mono.hdr.opcode);
1464 goto fail_cmd;
1465 }
1466 return 0;
1467fail_cmd:
1468 return -EINVAL;
1469}
1470
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001471int q6asm_enc_cfg_blk_qcelp(struct audio_client *ac, uint32_t frames_per_buf,
1472 uint16_t min_rate, uint16_t max_rate,
1473 uint16_t reduced_rate_level, uint16_t rate_modulation_cmd)
1474{
1475 struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
1476 int rc = 0;
1477
1478 pr_debug("%s:session[%d]frames[%d]min_rate[0x%4x]max_rate[0x%4x] \
1479 reduced_rate_level[0x%4x]rate_modulation_cmd[0x%4x]", __func__,
1480 ac->session, frames_per_buf, min_rate, max_rate,
1481 reduced_rate_level, rate_modulation_cmd);
1482
1483 q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
1484
1485 enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
1486
1487 enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
1488 enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
1489
1490 enc_cfg.enc_blk.frames_per_buf = frames_per_buf;
1491 enc_cfg.enc_blk.format_id = V13K_FS;
1492 enc_cfg.enc_blk.cfg_size = sizeof(struct asm_qcelp13_read_cfg);
1493 enc_cfg.enc_blk.cfg.qcelp13.min_rate = min_rate;
1494 enc_cfg.enc_blk.cfg.qcelp13.max_rate = max_rate;
1495 enc_cfg.enc_blk.cfg.qcelp13.reduced_rate_level = reduced_rate_level;
1496 enc_cfg.enc_blk.cfg.qcelp13.rate_modulation_cmd = rate_modulation_cmd;
1497
1498 rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
1499 if (rc < 0) {
1500 pr_err("Comamnd %d failed\n", ASM_STREAM_CMD_SET_ENCDEC_PARAM);
1501 goto fail_cmd;
1502 }
1503 rc = wait_event_timeout(ac->cmd_wait,
1504 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1505 if (!rc) {
1506 pr_err("timeout. waited for FORMAT_UPDATE\n");
1507 goto fail_cmd;
1508 }
1509 return 0;
1510fail_cmd:
1511 return -EINVAL;
1512}
1513
1514int q6asm_enc_cfg_blk_evrc(struct audio_client *ac, uint32_t frames_per_buf,
1515 uint16_t min_rate, uint16_t max_rate,
1516 uint16_t rate_modulation_cmd)
1517{
1518 struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
1519 int rc = 0;
1520
1521 pr_debug("%s:session[%d]frames[%d]min_rate[0x%4x]max_rate[0x%4x] \
1522 rate_modulation_cmd[0x%4x]", __func__, ac->session,
1523 frames_per_buf, min_rate, max_rate, rate_modulation_cmd);
1524
1525 q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
1526
1527 enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
1528
1529 enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
1530 enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
1531
1532 enc_cfg.enc_blk.frames_per_buf = frames_per_buf;
1533 enc_cfg.enc_blk.format_id = EVRC_FS;
1534 enc_cfg.enc_blk.cfg_size = sizeof(struct asm_evrc_read_cfg);
1535 enc_cfg.enc_blk.cfg.evrc.min_rate = min_rate;
1536 enc_cfg.enc_blk.cfg.evrc.max_rate = max_rate;
1537 enc_cfg.enc_blk.cfg.evrc.rate_modulation_cmd = rate_modulation_cmd;
1538 enc_cfg.enc_blk.cfg.evrc.reserved = 0;
1539
1540 rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
1541 if (rc < 0) {
1542 pr_err("Comamnd %d failed\n", ASM_STREAM_CMD_SET_ENCDEC_PARAM);
1543 goto fail_cmd;
1544 }
1545 rc = wait_event_timeout(ac->cmd_wait,
1546 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1547 if (!rc) {
1548 pr_err("timeout. waited for FORMAT_UPDATE\n");
1549 goto fail_cmd;
1550 }
1551 return 0;
1552fail_cmd:
1553 return -EINVAL;
1554}
1555
1556int q6asm_enc_cfg_blk_amrnb(struct audio_client *ac, uint32_t frames_per_buf,
1557 uint16_t band_mode, uint16_t dtx_enable)
1558{
1559 struct asm_stream_cmd_encdec_cfg_blk enc_cfg;
1560 int rc = 0;
1561
1562 pr_debug("%s:session[%d]frames[%d]band_mode[0x%4x]dtx_enable[0x%4x]",
1563 __func__, ac->session, frames_per_buf, band_mode, dtx_enable);
1564
1565 q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
1566
1567 enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
1568
1569 enc_cfg.param_id = ASM_ENCDEC_CFG_BLK_ID;
1570 enc_cfg.param_size = sizeof(struct asm_encode_cfg_blk);
1571
1572 enc_cfg.enc_blk.frames_per_buf = frames_per_buf;
1573 enc_cfg.enc_blk.format_id = AMRNB_FS;
1574 enc_cfg.enc_blk.cfg_size = sizeof(struct asm_amrnb_read_cfg);
1575 enc_cfg.enc_blk.cfg.amrnb.mode = band_mode;
1576 enc_cfg.enc_blk.cfg.amrnb.dtx_mode = dtx_enable;
1577
1578 rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
1579 if (rc < 0) {
1580 pr_err("Comamnd %d failed\n", ASM_STREAM_CMD_SET_ENCDEC_PARAM);
1581 goto fail_cmd;
1582 }
1583 rc = wait_event_timeout(ac->cmd_wait,
1584 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1585 if (!rc) {
1586 pr_err("timeout. waited for FORMAT_UPDATE\n");
1587 goto fail_cmd;
1588 }
1589 return 0;
1590fail_cmd:
1591 return -EINVAL;
1592}
1593
1594int q6asm_media_format_block_pcm(struct audio_client *ac,
1595 uint32_t rate, uint32_t channels)
1596{
1597 struct asm_stream_media_format_update fmt;
1598 int rc = 0;
1599
1600 pr_debug("%s:session[%d]rate[%d]ch[%d]\n", __func__, ac->session, rate,
1601 channels);
1602
1603 q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
1604
1605 fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
1606
1607 fmt.format = LINEAR_PCM;
1608 fmt.cfg_size = sizeof(struct asm_pcm_cfg);
1609 fmt.write_cfg.pcm_cfg.ch_cfg = channels;
1610 fmt.write_cfg.pcm_cfg.bits_per_sample = 16;
1611 fmt.write_cfg.pcm_cfg.sample_rate = rate;
1612 fmt.write_cfg.pcm_cfg.is_signed = 1;
1613 fmt.write_cfg.pcm_cfg.interleaved = 1;
1614
1615 rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
1616 if (rc < 0) {
1617 pr_err("%s:Comamnd open failed\n", __func__);
1618 goto fail_cmd;
1619 }
1620 rc = wait_event_timeout(ac->cmd_wait,
1621 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1622 if (!rc) {
1623 pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
1624 goto fail_cmd;
1625 }
1626 return 0;
1627fail_cmd:
1628 return -EINVAL;
1629}
1630
1631int q6asm_media_format_block_aac(struct audio_client *ac,
1632 struct asm_aac_cfg *cfg)
1633{
1634 struct asm_stream_media_format_update fmt;
1635 int rc = 0;
1636
1637 pr_debug("%s:session[%d]rate[%d]ch[%d]\n", __func__, ac->session,
1638 cfg->sample_rate, cfg->ch_cfg);
1639
1640 q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
1641
1642 fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
1643
1644 fmt.format = MPEG4_AAC;
1645 fmt.cfg_size = sizeof(struct asm_aac_cfg);
1646 fmt.write_cfg.aac_cfg.format = cfg->format;
1647 fmt.write_cfg.aac_cfg.aot = cfg->aot;
1648 fmt.write_cfg.aac_cfg.ep_config = cfg->ep_config;
1649 fmt.write_cfg.aac_cfg.section_data_resilience =
1650 cfg->section_data_resilience;
1651 fmt.write_cfg.aac_cfg.scalefactor_data_resilience =
1652 cfg->scalefactor_data_resilience;
1653 fmt.write_cfg.aac_cfg.spectral_data_resilience =
1654 cfg->spectral_data_resilience;
1655 fmt.write_cfg.aac_cfg.ch_cfg = cfg->ch_cfg;
1656 fmt.write_cfg.aac_cfg.sample_rate = cfg->sample_rate;
1657 pr_info("%s:format=%x cfg_size=%d aac-cfg=%x aot=%d ch=%d sr=%d\n",
1658 __func__, fmt.format, fmt.cfg_size,
1659 fmt.write_cfg.aac_cfg.format,
1660 fmt.write_cfg.aac_cfg.aot,
1661 fmt.write_cfg.aac_cfg.ch_cfg,
1662 fmt.write_cfg.aac_cfg.sample_rate);
1663 rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
1664 if (rc < 0) {
1665 pr_err("%s:Comamnd open failed\n", __func__);
1666 goto fail_cmd;
1667 }
1668 rc = wait_event_timeout(ac->cmd_wait,
1669 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1670 if (!rc) {
1671 pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
1672 goto fail_cmd;
1673 }
1674 return 0;
1675fail_cmd:
1676 return -EINVAL;
1677}
1678
1679int q6asm_media_format_block_wma(struct audio_client *ac,
1680 void *cfg)
1681{
1682 struct asm_stream_media_format_update fmt;
1683 struct asm_wma_cfg *wma_cfg = (struct asm_wma_cfg *)cfg;
1684 int rc = 0;
1685
1686 pr_debug("session[%d]format_tag[0x%4x] rate[%d] ch[0x%4x] bps[%d],\
1687 balign[0x%4x], bit_sample[0x%4x], ch_msk[%d], enc_opt[0x%4x]\n",
1688 ac->session, wma_cfg->format_tag, wma_cfg->sample_rate,
1689 wma_cfg->ch_cfg, wma_cfg->avg_bytes_per_sec,
1690 wma_cfg->block_align, wma_cfg->valid_bits_per_sample,
1691 wma_cfg->ch_mask, wma_cfg->encode_opt);
1692
1693 q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
1694
1695 fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
1696
1697 fmt.format = WMA_V9;
1698 fmt.cfg_size = sizeof(struct asm_wma_cfg);
1699 fmt.write_cfg.wma_cfg.format_tag = wma_cfg->format_tag;
1700 fmt.write_cfg.wma_cfg.ch_cfg = wma_cfg->ch_cfg;
1701 fmt.write_cfg.wma_cfg.sample_rate = wma_cfg->sample_rate;
1702 fmt.write_cfg.wma_cfg.avg_bytes_per_sec = wma_cfg->avg_bytes_per_sec;
1703 fmt.write_cfg.wma_cfg.block_align = wma_cfg->block_align;
1704 fmt.write_cfg.wma_cfg.valid_bits_per_sample =
1705 wma_cfg->valid_bits_per_sample;
1706 fmt.write_cfg.wma_cfg.ch_mask = wma_cfg->ch_mask;
1707 fmt.write_cfg.wma_cfg.encode_opt = wma_cfg->encode_opt;
1708 fmt.write_cfg.wma_cfg.adv_encode_opt = 0;
1709 fmt.write_cfg.wma_cfg.adv_encode_opt2 = 0;
1710 fmt.write_cfg.wma_cfg.drc_peak_ref = 0;
1711 fmt.write_cfg.wma_cfg.drc_peak_target = 0;
1712 fmt.write_cfg.wma_cfg.drc_ave_ref = 0;
1713 fmt.write_cfg.wma_cfg.drc_ave_target = 0;
1714
1715 rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
1716 if (rc < 0) {
1717 pr_err("%s:Comamnd open failed\n", __func__);
1718 goto fail_cmd;
1719 }
1720 rc = wait_event_timeout(ac->cmd_wait,
1721 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1722 if (!rc) {
1723 pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
1724 goto fail_cmd;
1725 }
1726 return 0;
1727fail_cmd:
1728 return -EINVAL;
1729}
1730
1731int q6asm_media_format_block_wmapro(struct audio_client *ac,
1732 void *cfg)
1733{
1734 struct asm_stream_media_format_update fmt;
1735 struct asm_wmapro_cfg *wmapro_cfg = (struct asm_wmapro_cfg *)cfg;
1736 int rc = 0;
1737
1738 pr_debug("session[%d]format_tag[0x%4x] rate[%d] ch[0x%4x] bps[%d],"
1739 "balign[0x%4x], bit_sample[0x%4x], ch_msk[%d], enc_opt[0x%4x],\
1740 adv_enc_opt[0x%4x], adv_enc_opt2[0x%8x]\n",
1741 ac->session, wmapro_cfg->format_tag, wmapro_cfg->sample_rate,
1742 wmapro_cfg->ch_cfg, wmapro_cfg->avg_bytes_per_sec,
1743 wmapro_cfg->block_align, wmapro_cfg->valid_bits_per_sample,
1744 wmapro_cfg->ch_mask, wmapro_cfg->encode_opt,
1745 wmapro_cfg->adv_encode_opt, wmapro_cfg->adv_encode_opt2);
1746
1747 q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
1748
1749 fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FORMAT_UPDATE;
1750
1751 fmt.format = WMA_V10PRO;
1752 fmt.cfg_size = sizeof(struct asm_wmapro_cfg);
1753 fmt.write_cfg.wmapro_cfg.format_tag = wmapro_cfg->format_tag;
1754 fmt.write_cfg.wmapro_cfg.ch_cfg = wmapro_cfg->ch_cfg;
1755 fmt.write_cfg.wmapro_cfg.sample_rate = wmapro_cfg->sample_rate;
1756 fmt.write_cfg.wmapro_cfg.avg_bytes_per_sec =
1757 wmapro_cfg->avg_bytes_per_sec;
1758 fmt.write_cfg.wmapro_cfg.block_align = wmapro_cfg->block_align;
1759 fmt.write_cfg.wmapro_cfg.valid_bits_per_sample =
1760 wmapro_cfg->valid_bits_per_sample;
1761 fmt.write_cfg.wmapro_cfg.ch_mask = wmapro_cfg->ch_mask;
1762 fmt.write_cfg.wmapro_cfg.encode_opt = wmapro_cfg->encode_opt;
1763 fmt.write_cfg.wmapro_cfg.adv_encode_opt = wmapro_cfg->adv_encode_opt;
1764 fmt.write_cfg.wmapro_cfg.adv_encode_opt2 = wmapro_cfg->adv_encode_opt2;
1765 fmt.write_cfg.wmapro_cfg.drc_peak_ref = 0;
1766 fmt.write_cfg.wmapro_cfg.drc_peak_target = 0;
1767 fmt.write_cfg.wmapro_cfg.drc_ave_ref = 0;
1768 fmt.write_cfg.wmapro_cfg.drc_ave_target = 0;
1769
1770 rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
1771 if (rc < 0) {
1772 pr_err("%s:Comamnd open failed\n", __func__);
1773 goto fail_cmd;
1774 }
1775 rc = wait_event_timeout(ac->cmd_wait,
1776 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1777 if (!rc) {
1778 pr_err("%s:timeout. waited for FORMAT_UPDATE\n", __func__);
1779 goto fail_cmd;
1780 }
1781 return 0;
1782fail_cmd:
1783 return -EINVAL;
1784}
1785
1786int q6asm_memory_map(struct audio_client *ac, uint32_t buf_add, int dir,
1787 uint32_t bufsz, uint32_t bufcnt)
1788{
1789 struct asm_stream_cmd_memory_map mem_map;
1790 int rc = 0;
1791
1792 if (!ac || ac->apr == NULL || this_mmap.apr == NULL) {
1793 pr_err("APR handle NULL\n");
1794 return -EINVAL;
1795 }
1796
1797 pr_debug("%s: Session[%d]\n", __func__, ac->session);
1798
1799 mem_map.hdr.opcode = ASM_SESSION_CMD_MEMORY_MAP;
1800
1801 mem_map.buf_add = buf_add;
1802 mem_map.buf_size = bufsz * bufcnt;
1803 mem_map.mempool_id = 0; /* EBI */
1804 mem_map.reserved = 0;
1805
1806 q6asm_add_mmaphdr(&mem_map.hdr,
1807 sizeof(struct asm_stream_cmd_memory_map), TRUE);
1808
1809 pr_debug("buf add[%x] buf_add_parameter[%x]\n",
1810 mem_map.buf_add, buf_add);
1811
1812 rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_map);
1813 if (rc < 0) {
1814 pr_err("mem_map op[0x%x]rc[%d]\n",
1815 mem_map.hdr.opcode, rc);
1816 rc = -EINVAL;
1817 goto fail_cmd;
1818 }
1819
1820 rc = wait_event_timeout(this_mmap.cmd_wait,
1821 (atomic_read(&this_mmap.cmd_state) == 0), 5 * HZ);
1822 if (!rc) {
1823 pr_err("timeout. waited for memory_map\n");
1824 rc = -EINVAL;
1825 goto fail_cmd;
1826 }
1827 rc = 0;
1828fail_cmd:
1829 return rc;
1830}
1831
1832int q6asm_memory_unmap(struct audio_client *ac, uint32_t buf_add, int dir)
1833{
1834 struct asm_stream_cmd_memory_unmap mem_unmap;
1835 int rc = 0;
1836
1837 if (!ac || ac->apr == NULL || this_mmap.apr == NULL) {
1838 pr_err("APR handle NULL\n");
1839 return -EINVAL;
1840 }
1841 pr_debug("%s: Session[%d]\n", __func__, ac->session);
1842
1843 q6asm_add_mmaphdr(&mem_unmap.hdr,
1844 sizeof(struct asm_stream_cmd_memory_unmap), TRUE);
1845 mem_unmap.hdr.opcode = ASM_SESSION_CMD_MEMORY_UNMAP;
1846 mem_unmap.buf_add = buf_add;
1847
1848 rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_unmap);
1849 if (rc < 0) {
1850 pr_err("mem_unmap op[0x%x]rc[%d]\n",
1851 mem_unmap.hdr.opcode, rc);
1852 rc = -EINVAL;
1853 goto fail_cmd;
1854 }
1855
1856 rc = wait_event_timeout(this_mmap.cmd_wait,
1857 (atomic_read(&this_mmap.cmd_state) == 0), 5 * HZ);
1858 if (!rc) {
1859 pr_err("timeout. waited for memory_map\n");
1860 rc = -EINVAL;
1861 goto fail_cmd;
1862 }
1863 rc = 0;
1864fail_cmd:
1865 return rc;
1866}
1867
1868int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain)
1869{
1870 void *vol_cmd = NULL;
1871 void *payload = NULL;
1872 struct asm_pp_params_command *cmd = NULL;
1873 struct asm_lrchannel_gain_params *lrgain = NULL;
1874 int sz = 0;
1875 int rc = 0;
1876
1877 sz = sizeof(struct asm_pp_params_command) +
1878 + sizeof(struct asm_lrchannel_gain_params);
1879 vol_cmd = kzalloc(sz, GFP_KERNEL);
1880 if (vol_cmd == NULL) {
1881 pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
1882 rc = -EINVAL;
1883 return rc;
1884 }
1885 cmd = (struct asm_pp_params_command *)vol_cmd;
1886 q6asm_add_hdr_async(ac, &cmd->hdr, sz, TRUE);
1887 cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
1888 cmd->payload = NULL;
1889 cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
1890 sizeof(struct asm_lrchannel_gain_params);
1891 cmd->params.module_id = VOLUME_CONTROL_MODULE_ID;
1892 cmd->params.param_id = L_R_CHANNEL_GAIN_PARAM_ID;
1893 cmd->params.param_size = sizeof(struct asm_lrchannel_gain_params);
1894 cmd->params.reserved = 0;
1895
1896 payload = (u8 *)(vol_cmd + sizeof(struct asm_pp_params_command));
1897 lrgain = (struct asm_lrchannel_gain_params *)payload;
1898
1899 lrgain->left_gain = left_gain;
1900 lrgain->right_gain = right_gain;
1901 rc = apr_send_pkt(ac->apr, (uint32_t *) vol_cmd);
1902 if (rc < 0) {
1903 pr_err("%s: Volume Command failed\n", __func__);
1904 rc = -EINVAL;
1905 goto fail_cmd;
1906 }
1907
1908 rc = wait_event_timeout(ac->cmd_wait,
1909 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
1910 if (!rc) {
1911 pr_err("%s: timeout in sending volume command to apr\n",
1912 __func__);
1913 rc = -EINVAL;
1914 goto fail_cmd;
1915 }
1916 rc = 0;
1917fail_cmd:
1918 kfree(vol_cmd);
1919 return rc;
1920}
1921
1922static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
1923 uint32_t bufsz, uint32_t bufcnt)
1924{
1925 struct asm_stream_cmd_memory_map_regions *mmap_regions = NULL;
1926 struct asm_memory_map_regions *mregions = NULL;
1927 struct audio_port_data *port = NULL;
1928 struct audio_buffer *ab = NULL;
1929 void *mmap_region_cmd = NULL;
1930 void *payload = NULL;
1931 int rc = 0;
1932 int i = 0;
1933 int cmd_size = 0;
1934
1935 if (!ac || ac->apr == NULL || this_mmap.apr == NULL) {
1936 pr_err("APR handle NULL\n");
1937 return -EINVAL;
1938 }
1939 pr_debug("%s: Session[%d]\n", __func__, ac->session);
1940
1941 cmd_size = sizeof(struct asm_stream_cmd_memory_map_regions)
1942 + sizeof(struct asm_memory_map_regions) * bufcnt;
1943
1944 mmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL);
Vasudeva Rao Thumati86edf6c2011-07-06 16:25:13 +05301945 if (mmap_region_cmd == NULL) {
1946 pr_err("%s: Mem alloc failed\n", __func__);
1947 rc = -EINVAL;
1948 return rc;
1949 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001950 mmap_regions = (struct asm_stream_cmd_memory_map_regions *)
1951 mmap_region_cmd;
1952 q6asm_add_mmaphdr(&mmap_regions->hdr, cmd_size, TRUE);
1953 mmap_regions->hdr.opcode = ASM_SESSION_CMD_MEMORY_MAP_REGIONS;
1954 mmap_regions->mempool_id = 0;
1955 mmap_regions->nregions = bufcnt & 0x00ff;
1956 pr_debug("map_regions->nregions = %d\n", mmap_regions->nregions);
1957 payload = ((u8 *) mmap_region_cmd +
1958 sizeof(struct asm_stream_cmd_memory_map_regions));
1959 mregions = (struct asm_memory_map_regions *)payload;
1960
1961 port = &ac->port[dir];
1962 for (i = 0; i < bufcnt; i++) {
1963 ab = &port->buf[i];
1964 mregions->phys = ab->phys;
1965 mregions->buf_size = ab->size;
1966 ++mregions;
1967 }
1968
1969 rc = apr_send_pkt(this_mmap.apr, (uint32_t *) mmap_region_cmd);
1970 if (rc < 0) {
1971 pr_err("mmap_regions op[0x%x]rc[%d]\n",
1972 mmap_regions->hdr.opcode, rc);
1973 rc = -EINVAL;
1974 goto fail_cmd;
1975 }
1976
1977 rc = wait_event_timeout(this_mmap.cmd_wait,
1978 (atomic_read(&this_mmap.cmd_state) == 0), 5*HZ);
1979 if (!rc) {
1980 pr_err("timeout. waited for memory_map\n");
1981 rc = -EINVAL;
1982 goto fail_cmd;
1983 }
1984 rc = 0;
1985fail_cmd:
1986 kfree(mmap_region_cmd);
1987 return rc;
1988}
1989
1990static int q6asm_memory_unmap_regions(struct audio_client *ac, int dir,
1991 uint32_t bufsz, uint32_t bufcnt)
1992{
1993 struct asm_stream_cmd_memory_unmap_regions *unmap_regions = NULL;
1994 struct asm_memory_unmap_regions *mregions = NULL;
1995 struct audio_port_data *port = NULL;
1996 struct audio_buffer *ab = NULL;
1997 void *unmap_region_cmd = NULL;
1998 void *payload = NULL;
1999 int rc = 0;
2000 int i = 0;
2001 int cmd_size = 0;
2002
2003 if (!ac || ac->apr == NULL || this_mmap.apr == NULL) {
2004 pr_err("APR handle NULL\n");
2005 return -EINVAL;
2006 }
2007 pr_debug("%s: Session[%d]\n", __func__, ac->session);
2008
2009 cmd_size = sizeof(struct asm_stream_cmd_memory_unmap_regions) +
2010 sizeof(struct asm_memory_unmap_regions) * bufcnt;
2011
2012 unmap_region_cmd = kzalloc(cmd_size, GFP_KERNEL);
Vasudeva Rao Thumati86edf6c2011-07-06 16:25:13 +05302013 if (unmap_region_cmd == NULL) {
2014 pr_err("%s: Mem alloc failed\n", __func__);
2015 rc = -EINVAL;
2016 return rc;
2017 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002018 unmap_regions = (struct asm_stream_cmd_memory_unmap_regions *)
2019 unmap_region_cmd;
2020 q6asm_add_mmaphdr(&unmap_regions->hdr, cmd_size, TRUE);
2021 unmap_regions->hdr.opcode = ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS;
2022 unmap_regions->nregions = bufcnt & 0x00ff;
2023 pr_debug("unmap_regions->nregions = %d\n", unmap_regions->nregions);
2024 payload = ((u8 *) unmap_region_cmd +
2025 sizeof(struct asm_stream_cmd_memory_unmap_regions));
2026 mregions = (struct asm_memory_unmap_regions *)payload;
2027 port = &ac->port[dir];
2028 for (i = 0; i < bufcnt; i++) {
2029 ab = &port->buf[i];
2030 mregions->phys = ab->phys;
2031 ++mregions;
2032 }
2033
2034 rc = apr_send_pkt(this_mmap.apr, (uint32_t *) unmap_region_cmd);
2035 if (rc < 0) {
2036 pr_err("mmap_regions op[0x%x]rc[%d]\n",
2037 unmap_regions->hdr.opcode, rc);
2038 goto fail_cmd;
2039 }
2040
2041 rc = wait_event_timeout(this_mmap.cmd_wait,
2042 (atomic_read(&this_mmap.cmd_state) == 0), 5*HZ);
2043 if (!rc) {
2044 pr_err("timeout. waited for memory_unmap\n");
2045 goto fail_cmd;
2046 }
2047 rc = 0;
2048
2049fail_cmd:
2050 kfree(unmap_region_cmd);
2051 return rc;
2052}
2053
2054int q6asm_set_mute(struct audio_client *ac, int muteflag)
2055{
2056 void *vol_cmd = NULL;
2057 void *payload = NULL;
2058 struct asm_pp_params_command *cmd = NULL;
2059 struct asm_mute_params *mute = NULL;
2060 int sz = 0;
2061 int rc = 0;
2062
2063 sz = sizeof(struct asm_pp_params_command) +
2064 + sizeof(struct asm_mute_params);
2065 vol_cmd = kzalloc(sz, GFP_KERNEL);
2066 if (vol_cmd == NULL) {
2067 pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
2068 rc = -EINVAL;
2069 return rc;
2070 }
2071 cmd = (struct asm_pp_params_command *)vol_cmd;
2072 q6asm_add_hdr_async(ac, &cmd->hdr, sz, TRUE);
2073 cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
2074 cmd->payload = NULL;
2075 cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
2076 sizeof(struct asm_mute_params);
2077 cmd->params.module_id = VOLUME_CONTROL_MODULE_ID;
2078 cmd->params.param_id = MUTE_CONFIG_PARAM_ID;
2079 cmd->params.param_size = sizeof(struct asm_mute_params);
2080 cmd->params.reserved = 0;
2081
2082 payload = (u8 *)(vol_cmd + sizeof(struct asm_pp_params_command));
2083 mute = (struct asm_mute_params *)payload;
2084
2085 mute->muteflag = muteflag;
2086 rc = apr_send_pkt(ac->apr, (uint32_t *) vol_cmd);
2087 if (rc < 0) {
2088 pr_err("%s: Mute Command failed\n", __func__);
2089 rc = -EINVAL;
2090 goto fail_cmd;
2091 }
2092
2093 rc = wait_event_timeout(ac->cmd_wait,
2094 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
2095 if (!rc) {
2096 pr_err("%s: timeout in sending mute command to apr\n",
2097 __func__);
2098 rc = -EINVAL;
2099 goto fail_cmd;
2100 }
2101 rc = 0;
2102fail_cmd:
2103 kfree(vol_cmd);
2104 return rc;
2105}
2106
2107int q6asm_set_volume(struct audio_client *ac, int volume)
2108{
2109 void *vol_cmd = NULL;
2110 void *payload = NULL;
2111 struct asm_pp_params_command *cmd = NULL;
2112 struct asm_master_gain_params *mgain = NULL;
2113 int sz = 0;
2114 int rc = 0;
2115
2116 sz = sizeof(struct asm_pp_params_command) +
2117 + sizeof(struct asm_master_gain_params);
2118 vol_cmd = kzalloc(sz, GFP_KERNEL);
2119 if (vol_cmd == NULL) {
2120 pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
2121 rc = -EINVAL;
2122 return rc;
2123 }
2124 cmd = (struct asm_pp_params_command *)vol_cmd;
2125 q6asm_add_hdr_async(ac, &cmd->hdr, sz, TRUE);
2126 cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
2127 cmd->payload = NULL;
2128 cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
2129 sizeof(struct asm_master_gain_params);
2130 cmd->params.module_id = VOLUME_CONTROL_MODULE_ID;
2131 cmd->params.param_id = MASTER_GAIN_PARAM_ID;
2132 cmd->params.param_size = sizeof(struct asm_master_gain_params);
2133 cmd->params.reserved = 0;
2134
2135 payload = (u8 *)(vol_cmd + sizeof(struct asm_pp_params_command));
2136 mgain = (struct asm_master_gain_params *)payload;
2137
2138 mgain->master_gain = volume;
2139 mgain->padding = 0x00;
2140 rc = apr_send_pkt(ac->apr, (uint32_t *) vol_cmd);
2141 if (rc < 0) {
2142 pr_err("%s: Volume Command failed\n", __func__);
2143 rc = -EINVAL;
2144 goto fail_cmd;
2145 }
2146
2147 rc = wait_event_timeout(ac->cmd_wait,
2148 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
2149 if (!rc) {
2150 pr_err("%s: timeout in sending volume command to apr\n",
2151 __func__);
2152 rc = -EINVAL;
2153 goto fail_cmd;
2154 }
2155 rc = 0;
2156fail_cmd:
2157 kfree(vol_cmd);
2158 return rc;
2159}
2160
2161int q6asm_set_softpause(struct audio_client *ac,
2162 struct asm_softpause_params *pause_param)
2163{
2164 void *vol_cmd = NULL;
2165 void *payload = NULL;
2166 struct asm_pp_params_command *cmd = NULL;
2167 struct asm_softpause_params *params = NULL;
2168 int sz = 0;
2169 int rc = 0;
2170
2171 sz = sizeof(struct asm_pp_params_command) +
2172 + sizeof(struct asm_softpause_params);
2173 vol_cmd = kzalloc(sz, GFP_KERNEL);
2174 if (vol_cmd == NULL) {
2175 pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
2176 rc = -EINVAL;
2177 return rc;
2178 }
2179 cmd = (struct asm_pp_params_command *)vol_cmd;
2180 q6asm_add_hdr_async(ac, &cmd->hdr, sz, TRUE);
2181 cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
2182 cmd->payload = NULL;
2183 cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
2184 sizeof(struct asm_softpause_params);
2185 cmd->params.module_id = VOLUME_CONTROL_MODULE_ID;
2186 cmd->params.param_id = SOFT_PAUSE_PARAM_ID;
2187 cmd->params.param_size = sizeof(struct asm_softpause_params);
2188 cmd->params.reserved = 0;
2189
2190 payload = (u8 *)(vol_cmd + sizeof(struct asm_pp_params_command));
2191 params = (struct asm_softpause_params *)payload;
2192
2193 params->enable = pause_param->enable;
2194 params->period = pause_param->period;
2195 params->step = pause_param->step;
2196 params->rampingcurve = pause_param->rampingcurve;
2197 pr_debug("%s: soft Pause Command: enable = %d, period = %d,"
2198 "step = %d, curve = %d\n", __func__, params->enable,
2199 params->period, params->step, params->rampingcurve);
2200 rc = apr_send_pkt(ac->apr, (uint32_t *) vol_cmd);
2201 if (rc < 0) {
2202 pr_err("%s: Volume Command(soft_pause) failed\n", __func__);
2203 rc = -EINVAL;
2204 goto fail_cmd;
2205 }
2206
2207 rc = wait_event_timeout(ac->cmd_wait,
2208 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
2209 if (!rc) {
2210 pr_err("%s: timeout in sending volume command(soft_pause)"
2211 "to apr\n", __func__);
2212 rc = -EINVAL;
2213 goto fail_cmd;
2214 }
2215 rc = 0;
2216fail_cmd:
2217 kfree(vol_cmd);
2218 return rc;
2219}
2220
2221int q6asm_equalizer(struct audio_client *ac, void *eq)
2222{
2223 void *eq_cmd = NULL;
2224 void *payload = NULL;
2225 struct asm_pp_params_command *cmd = NULL;
2226 struct asm_equalizer_params *equalizer = NULL;
2227 struct msm_audio_eq_stream_config *eq_params = NULL;
2228 int i = 0;
2229 int sz = 0;
2230 int rc = 0;
2231
2232 sz = sizeof(struct asm_pp_params_command) +
2233 + sizeof(struct asm_equalizer_params);
2234 eq_cmd = kzalloc(sz, GFP_KERNEL);
2235 if (eq_cmd == NULL) {
2236 pr_err("%s[%d]: Mem alloc failed\n", __func__, ac->session);
2237 rc = -EINVAL;
2238 goto fail_cmd;
2239 }
2240 eq_params = (struct msm_audio_eq_stream_config *) eq;
2241 cmd = (struct asm_pp_params_command *)eq_cmd;
2242 q6asm_add_hdr(ac, &cmd->hdr, sz, TRUE);
2243 cmd->hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS;
2244 cmd->payload = NULL;
2245 cmd->payload_size = sizeof(struct asm_pp_param_data_hdr) +
2246 sizeof(struct asm_equalizer_params);
2247 cmd->params.module_id = EQUALIZER_MODULE_ID;
2248 cmd->params.param_id = EQUALIZER_PARAM_ID;
2249 cmd->params.param_size = sizeof(struct asm_equalizer_params);
2250 cmd->params.reserved = 0;
2251 payload = (u8 *)(eq_cmd + sizeof(struct asm_pp_params_command));
2252 equalizer = (struct asm_equalizer_params *)payload;
2253
2254 equalizer->enable = eq_params->enable;
2255 equalizer->num_bands = eq_params->num_bands;
2256 pr_debug("%s: enable:%d numbands:%d\n", __func__, eq_params->enable,
2257 eq_params->num_bands);
2258 for (i = 0; i < eq_params->num_bands; i++) {
2259 equalizer->eq_bands[i].band_idx =
2260 eq_params->eq_bands[i].band_idx;
2261 equalizer->eq_bands[i].filter_type =
2262 eq_params->eq_bands[i].filter_type;
2263 equalizer->eq_bands[i].center_freq_hz =
2264 eq_params->eq_bands[i].center_freq_hz;
2265 equalizer->eq_bands[i].filter_gain =
2266 eq_params->eq_bands[i].filter_gain;
2267 equalizer->eq_bands[i].q_factor =
2268 eq_params->eq_bands[i].q_factor;
2269 pr_debug("%s: filter_type:%u bandnum:%d\n", __func__,
2270 eq_params->eq_bands[i].filter_type, i);
2271 pr_debug("%s: center_freq_hz:%u bandnum:%d\n", __func__,
2272 eq_params->eq_bands[i].center_freq_hz, i);
2273 pr_debug("%s: filter_gain:%d bandnum:%d\n", __func__,
2274 eq_params->eq_bands[i].filter_gain, i);
2275 pr_debug("%s: q_factor:%d bandnum:%d\n", __func__,
2276 eq_params->eq_bands[i].q_factor, i);
2277 }
2278 rc = apr_send_pkt(ac->apr, (uint32_t *) eq_cmd);
2279 if (rc < 0) {
2280 pr_err("%s: Equalizer Command failed\n", __func__);
2281 rc = -EINVAL;
2282 goto fail_cmd;
2283 }
2284
2285 rc = wait_event_timeout(ac->cmd_wait,
2286 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
2287 if (!rc) {
2288 pr_err("%s: timeout in sending equalizer command to apr\n",
2289 __func__);
2290 rc = -EINVAL;
2291 goto fail_cmd;
2292 }
2293 rc = 0;
2294fail_cmd:
2295 kfree(eq_cmd);
2296 return rc;
2297}
2298
2299int q6asm_read(struct audio_client *ac)
2300{
2301 struct asm_stream_cmd_read read;
2302 struct audio_buffer *ab;
2303 int dsp_buf;
2304 struct audio_port_data *port;
2305 int rc;
2306 if (!ac || ac->apr == NULL) {
2307 pr_err("APR handle NULL\n");
2308 return -EINVAL;
2309 }
2310 if (ac->io_mode == SYNC_IO_MODE) {
2311 port = &ac->port[OUT];
2312
2313 q6asm_add_hdr(ac, &read.hdr, sizeof(read), FALSE);
2314
2315 mutex_lock(&port->lock);
2316
2317 dsp_buf = port->dsp_buf;
2318 ab = &port->buf[dsp_buf];
2319
2320 pr_debug("%s:session[%d]dsp-buf[%d][%p]cpu_buf[%d][%p]\n",
2321 __func__,
2322 ac->session,
2323 dsp_buf,
2324 (void *)port->buf[dsp_buf].data,
2325 port->cpu_buf,
2326 (void *)port->buf[port->cpu_buf].phys);
2327
2328 read.hdr.opcode = ASM_DATA_CMD_READ;
2329 read.buf_add = ab->phys;
2330 read.buf_size = ab->size;
2331 read.uid = port->dsp_buf;
2332 read.hdr.token = port->dsp_buf;
2333
2334 port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
2335 mutex_unlock(&port->lock);
2336 pr_debug("%s:buf add[0x%x] token[%d] uid[%d]\n", __func__,
2337 read.buf_add,
2338 read.hdr.token,
2339 read.uid);
2340 rc = apr_send_pkt(ac->apr, (uint32_t *) &read);
2341 if (rc < 0) {
2342 pr_err("read op[0x%x]rc[%d]\n", read.hdr.opcode, rc);
2343 goto fail_cmd;
2344 }
2345 return 0;
2346 }
2347fail_cmd:
2348 return -EINVAL;
2349}
2350
2351int q6asm_read_nolock(struct audio_client *ac)
2352{
2353 struct asm_stream_cmd_read read;
2354 struct audio_buffer *ab;
2355 int dsp_buf;
2356 struct audio_port_data *port;
2357 int rc;
2358 if (!ac || ac->apr == NULL) {
2359 pr_err("APR handle NULL\n");
2360 return -EINVAL;
2361 }
2362 if (ac->io_mode == SYNC_IO_MODE) {
2363 port = &ac->port[OUT];
2364
2365 q6asm_add_hdr_async(ac, &read.hdr, sizeof(read), FALSE);
2366
2367
2368 dsp_buf = port->dsp_buf;
2369 ab = &port->buf[dsp_buf];
2370
2371 pr_debug("%s:session[%d]dsp-buf[%d][%p]cpu_buf[%d][%p]\n",
2372 __func__,
2373 ac->session,
2374 dsp_buf,
2375 (void *)port->buf[dsp_buf].data,
2376 port->cpu_buf,
2377 (void *)port->buf[port->cpu_buf].phys);
2378
2379 read.hdr.opcode = ASM_DATA_CMD_READ;
2380 read.buf_add = ab->phys;
2381 read.buf_size = ab->size;
2382 read.uid = port->dsp_buf;
2383 read.hdr.token = port->dsp_buf;
2384
2385 port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
2386 pr_debug("%s:buf add[0x%x] token[%d] uid[%d]\n", __func__,
2387 read.buf_add,
2388 read.hdr.token,
2389 read.uid);
2390 rc = apr_send_pkt(ac->apr, (uint32_t *) &read);
2391 if (rc < 0) {
2392 pr_err("read op[0x%x]rc[%d]\n", read.hdr.opcode, rc);
2393 goto fail_cmd;
2394 }
2395 return 0;
2396 }
2397fail_cmd:
2398 return -EINVAL;
2399}
2400
2401
2402static void q6asm_add_hdr_async(struct audio_client *ac, struct apr_hdr *hdr,
2403 uint32_t pkt_size, uint32_t cmd_flg)
2404{
2405 pr_debug("session=%d pkt size=%d cmd_flg=%d\n", pkt_size, cmd_flg,
2406 ac->session);
2407 hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
2408 APR_HDR_LEN(sizeof(struct apr_hdr)),\
2409 APR_PKT_VER);
2410 hdr->src_svc = ((struct apr_svc *)ac->apr)->id;
2411 hdr->src_domain = APR_DOMAIN_APPS;
2412 hdr->dest_svc = APR_SVC_ASM;
2413 hdr->dest_domain = APR_DOMAIN_ADSP;
2414 hdr->src_port = ((ac->session << 8) & 0xFF00) | 0x01;
2415 hdr->dest_port = ((ac->session << 8) & 0xFF00) | 0x01;
2416 if (cmd_flg) {
2417 hdr->token = ac->session;
2418 atomic_set(&ac->cmd_state, 1);
2419 }
2420 hdr->pkt_size = pkt_size;
2421 return;
2422}
2423
2424int q6asm_async_write(struct audio_client *ac,
2425 struct audio_aio_write_param *param)
2426{
2427 int rc = 0;
2428 struct asm_stream_cmd_write write;
2429
2430 if (!ac || ac->apr == NULL) {
2431 pr_err("%s: APR handle NULL\n", __func__);
2432 return -EINVAL;
2433 }
2434
2435 q6asm_add_hdr_async(ac, &write.hdr, sizeof(write), FALSE);
2436
2437 /* Pass physical address as token for AIO scheme */
2438 write.hdr.token = param->uid;
2439 write.hdr.opcode = ASM_DATA_CMD_WRITE;
2440 write.buf_add = param->paddr;
2441 write.avail_bytes = param->len;
2442 write.uid = param->uid;
2443 write.msw_ts = param->msw_ts;
2444 write.lsw_ts = param->lsw_ts;
2445 /* Use 0xFF00 for disabling timestamps */
2446 if (param->flags == 0xFF00)
2447 write.uflags = (0x00000000 | (param->flags & 0x800000FF));
2448 else
2449 write.uflags = (0x80000000 | param->flags);
2450
2451 pr_debug("%s: session[%d] bufadd[0x%x]len[0x%x]", __func__, ac->session,
2452 write.buf_add, write.avail_bytes);
2453
2454 rc = apr_send_pkt(ac->apr, (uint32_t *) &write);
2455 if (rc < 0) {
2456 pr_debug("[%s] write op[0x%x]rc[%d]\n", __func__,
2457 write.hdr.opcode, rc);
2458 goto fail_cmd;
2459 }
2460 return 0;
2461fail_cmd:
2462 return -EINVAL;
2463}
2464
2465int q6asm_async_read(struct audio_client *ac,
2466 struct audio_aio_read_param *param)
2467{
2468 int rc = 0;
2469 struct asm_stream_cmd_read read;
2470
2471 if (!ac || ac->apr == NULL) {
2472 pr_err("%s: APR handle NULL\n", __func__);
2473 return -EINVAL;
2474 }
2475
2476 q6asm_add_hdr_async(ac, &read.hdr, sizeof(read), FALSE);
2477
2478 /* Pass physical address as token for AIO scheme */
2479 read.hdr.token = param->paddr;
2480 read.hdr.opcode = ASM_DATA_CMD_READ;
2481 read.buf_add = param->paddr;
2482 read.buf_size = param->len;
2483 read.uid = param->uid;
2484
2485 pr_debug("%s: session[%d] bufadd[0x%x]len[0x%x]", __func__, ac->session,
2486 read.buf_add, read.buf_size);
2487
2488 rc = apr_send_pkt(ac->apr, (uint32_t *) &read);
2489 if (rc < 0) {
2490 pr_debug("[%s] read op[0x%x]rc[%d]\n", __func__,
2491 read.hdr.opcode, rc);
2492 goto fail_cmd;
2493 }
2494 return 0;
2495fail_cmd:
2496 return -EINVAL;
2497}
2498
2499int q6asm_write(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
2500 uint32_t lsw_ts, uint32_t flags)
2501{
2502 int rc = 0;
2503 struct asm_stream_cmd_write write;
2504 struct audio_port_data *port;
2505 struct audio_buffer *ab;
2506 int dsp_buf = 0;
2507
2508 if (!ac || ac->apr == NULL) {
2509 pr_err("APR handle NULL\n");
2510 return -EINVAL;
2511 }
2512 pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
2513 if (ac->io_mode == SYNC_IO_MODE) {
2514 port = &ac->port[IN];
2515
2516 q6asm_add_hdr(ac, &write.hdr, sizeof(write),
2517 FALSE);
2518 mutex_lock(&port->lock);
2519
2520 dsp_buf = port->dsp_buf;
2521 ab = &port->buf[dsp_buf];
2522
2523 write.hdr.token = port->dsp_buf;
2524 write.hdr.opcode = ASM_DATA_CMD_WRITE;
2525 write.buf_add = ab->phys;
2526 write.avail_bytes = len;
2527 write.uid = port->dsp_buf;
2528 write.msw_ts = msw_ts;
2529 write.lsw_ts = lsw_ts;
2530 /* Use 0xFF00 for disabling timestamps */
2531 if (flags == 0xFF00)
2532 write.uflags = (0x00000000 | (flags & 0x800000FF));
2533 else
2534 write.uflags = (0x80000000 | flags);
2535 port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
2536
2537 pr_debug("%s:ab->phys[0x%x]bufadd[0x%x]token[0x%x]buf_id[0x%x]"
2538 , __func__,
2539 ab->phys,
2540 write.buf_add,
2541 write.hdr.token,
2542 write.uid);
2543 mutex_unlock(&port->lock);
Rajesha Kini3498c932011-07-19 19:58:27 +05302544#ifdef CONFIG_DEBUG_FS
2545 if (out_enable_flag) {
2546 char zero_pattern[2] = {0x00, 0x00};
2547 /* If First two byte is non zero and last two byte
2548 is zero then it is warm output pattern */
2549 if ((strncmp(((char *)ab->data), zero_pattern, 2)) &&
2550 (!strncmp(((char *)ab->data + 2), zero_pattern, 2))) {
2551 do_gettimeofday(&out_warm_tv);
2552 pr_debug("WARM:apr_send_pkt at \
2553 %ld sec %ld microsec\n", out_warm_tv.tv_sec,\
2554 out_warm_tv.tv_usec);
2555 pr_debug("Warm Pattern Matched");
2556 }
2557 /* If First two byte is zero and last two byte is
2558 non zero then it is cont ouput pattern */
2559 else if ((!strncmp(((char *)ab->data), zero_pattern, 2))
2560 && (strncmp(((char *)ab->data + 2), zero_pattern, 2))) {
2561 do_gettimeofday(&out_cont_tv);
2562 pr_debug("CONT:apr_send_pkt at \
2563 %ld sec %ld microsec\n", out_cont_tv.tv_sec,\
2564 out_cont_tv.tv_usec);
2565 pr_debug("Cont Pattern Matched");
2566 }
2567 }
2568#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002569 rc = apr_send_pkt(ac->apr, (uint32_t *) &write);
2570 if (rc < 0) {
2571 pr_err("write op[0x%x]rc[%d]\n", write.hdr.opcode, rc);
2572 goto fail_cmd;
2573 }
2574 pr_debug("%s: WRITE SUCCESS\n", __func__);
2575 return 0;
2576 }
2577fail_cmd:
2578 return -EINVAL;
2579}
2580
2581int q6asm_write_nolock(struct audio_client *ac, uint32_t len, uint32_t msw_ts,
2582 uint32_t lsw_ts, uint32_t flags)
2583{
2584 int rc = 0;
2585 struct asm_stream_cmd_write write;
2586 struct audio_port_data *port;
2587 struct audio_buffer *ab;
2588 int dsp_buf = 0;
2589
2590 if (!ac || ac->apr == NULL) {
2591 pr_err("APR handle NULL\n");
2592 return -EINVAL;
2593 }
2594 pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
2595 if (ac->io_mode == SYNC_IO_MODE) {
2596 port = &ac->port[IN];
2597
2598 q6asm_add_hdr_async(ac, &write.hdr, sizeof(write),
2599 FALSE);
2600
2601 dsp_buf = port->dsp_buf;
2602 ab = &port->buf[dsp_buf];
2603
2604 write.hdr.token = port->dsp_buf;
2605 write.hdr.opcode = ASM_DATA_CMD_WRITE;
2606 write.buf_add = ab->phys;
2607 write.avail_bytes = len;
2608 write.uid = port->dsp_buf;
2609 write.msw_ts = msw_ts;
2610 write.lsw_ts = lsw_ts;
2611 /* Use 0xFF00 for disabling timestamps */
2612 if (flags == 0xFF00)
2613 write.uflags = (0x00000000 | (flags & 0x800000FF));
2614 else
2615 write.uflags = (0x80000000 | flags);
2616 port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
2617
2618 pr_debug("%s:ab->phys[0x%x]bufadd[0x%x]token[0x%x]buf_id[0x%x]"
2619 , __func__,
2620 ab->phys,
2621 write.buf_add,
2622 write.hdr.token,
2623 write.uid);
2624
2625 rc = apr_send_pkt(ac->apr, (uint32_t *) &write);
2626 if (rc < 0) {
2627 pr_err("write op[0x%x]rc[%d]\n", write.hdr.opcode, rc);
2628 goto fail_cmd;
2629 }
2630 pr_debug("%s: WRITE SUCCESS\n", __func__);
2631 return 0;
2632 }
2633fail_cmd:
2634 return -EINVAL;
2635}
2636
2637uint64_t q6asm_get_session_time(struct audio_client *ac)
2638{
2639 struct apr_hdr hdr;
2640 int rc;
2641
2642 if (!ac || ac->apr == NULL) {
2643 pr_err("APR handle NULL\n");
2644 return -EINVAL;
2645 }
2646 q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE);
2647 hdr.opcode = ASM_SESSION_CMD_GET_SESSION_TIME;
2648 atomic_set(&ac->time_flag, 1);
2649
2650 pr_debug("%s: session[%d]opcode[0x%x]\n", __func__,
2651 ac->session,
2652 hdr.opcode);
2653 rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr);
2654 if (rc < 0) {
2655 pr_err("Commmand 0x%x failed\n", hdr.opcode);
2656 goto fail_cmd;
2657 }
2658 rc = wait_event_timeout(ac->time_wait,
2659 (atomic_read(&ac->time_flag) == 0), 5*HZ);
2660 if (!rc) {
2661 pr_err("%s: timeout in getting session time from DSP\n",
2662 __func__);
2663 goto fail_cmd;
2664 }
2665 return ac->time_stamp;
2666
2667fail_cmd:
2668 return -EINVAL;
2669}
2670
2671int q6asm_cmd(struct audio_client *ac, int cmd)
2672{
2673 struct apr_hdr hdr;
2674 int rc;
2675 atomic_t *state;
2676 int cnt = 0;
2677
2678 if (!ac || ac->apr == NULL) {
2679 pr_err("APR handle NULL\n");
2680 return -EINVAL;
2681 }
2682 q6asm_add_hdr(ac, &hdr, sizeof(hdr), TRUE);
2683 switch (cmd) {
2684 case CMD_PAUSE:
2685 pr_debug("%s:CMD_PAUSE\n", __func__);
2686 hdr.opcode = ASM_SESSION_CMD_PAUSE;
2687 state = &ac->cmd_state;
2688 break;
2689 case CMD_FLUSH:
2690 pr_debug("%s:CMD_FLUSH\n", __func__);
2691 hdr.opcode = ASM_STREAM_CMD_FLUSH;
2692 state = &ac->cmd_state;
2693 break;
2694 case CMD_OUT_FLUSH:
2695 pr_debug("%s:CMD_OUT_FLUSH\n", __func__);
2696 hdr.opcode = ASM_STREAM_CMD_FLUSH_READBUFS;
2697 state = &ac->cmd_state;
2698 break;
2699 case CMD_EOS:
2700 pr_debug("%s:CMD_EOS\n", __func__);
2701 hdr.opcode = ASM_DATA_CMD_EOS;
2702 atomic_set(&ac->cmd_state, 0);
2703 state = &ac->cmd_state;
2704 break;
2705 case CMD_CLOSE:
2706 pr_debug("%s:CMD_CLOSE\n", __func__);
2707 hdr.opcode = ASM_STREAM_CMD_CLOSE;
2708 state = &ac->cmd_state;
2709 break;
2710 default:
2711 pr_err("Invalid format[%d]\n", cmd);
2712 goto fail_cmd;
2713 }
2714 pr_debug("%s:session[%d]opcode[0x%x] ", __func__,
2715 ac->session,
2716 hdr.opcode);
2717 rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr);
2718 if (rc < 0) {
2719 pr_err("Commmand 0x%x failed\n", hdr.opcode);
2720 goto fail_cmd;
2721 }
2722 rc = wait_event_timeout(ac->cmd_wait, (atomic_read(state) == 0), 5*HZ);
2723 if (!rc) {
2724 pr_err("timeout. waited for response opcode[0x%x]\n",
2725 hdr.opcode);
2726 goto fail_cmd;
2727 }
2728 if (cmd == CMD_FLUSH)
2729 q6asm_reset_buf_state(ac);
2730 if (cmd == CMD_CLOSE) {
2731 /* check if DSP return all buffers */
2732 if (ac->port[IN].buf) {
2733 for (cnt = 0; cnt < ac->port[IN].max_buf_cnt;
2734 cnt++) {
2735 if (ac->port[IN].buf[cnt].used == IN) {
2736 pr_debug("Write Buf[%d] not returned\n",
2737 cnt);
2738 }
2739 }
2740 }
2741 if (ac->port[OUT].buf) {
2742 for (cnt = 0; cnt < ac->port[OUT].max_buf_cnt; cnt++) {
2743 if (ac->port[OUT].buf[cnt].used == OUT) {
2744 pr_debug("Read Buf[%d] not returned\n",
2745 cnt);
2746 }
2747 }
2748 }
2749 }
2750 return 0;
2751fail_cmd:
2752 return -EINVAL;
2753}
2754
2755int q6asm_cmd_nowait(struct audio_client *ac, int cmd)
2756{
2757 struct apr_hdr hdr;
2758 int rc;
2759
2760 if (!ac || ac->apr == NULL) {
2761 pr_err("%s:APR handle NULL\n", __func__);
2762 return -EINVAL;
2763 }
2764 q6asm_add_hdr_async(ac, &hdr, sizeof(hdr), TRUE);
2765 switch (cmd) {
2766 case CMD_PAUSE:
2767 pr_debug("%s:CMD_PAUSE\n", __func__);
2768 hdr.opcode = ASM_SESSION_CMD_PAUSE;
2769 break;
2770 case CMD_EOS:
2771 pr_debug("%s:CMD_EOS\n", __func__);
2772 hdr.opcode = ASM_DATA_CMD_EOS;
2773 break;
2774 default:
2775 pr_err("%s:Invalid format[%d]\n", __func__, cmd);
2776 goto fail_cmd;
2777 }
2778 pr_debug("%s:session[%d]opcode[0x%x] ", __func__,
2779 ac->session,
2780 hdr.opcode);
2781 rc = apr_send_pkt(ac->apr, (uint32_t *) &hdr);
2782 if (rc < 0) {
2783 pr_err("%s:Commmand 0x%x failed\n", __func__, hdr.opcode);
2784 goto fail_cmd;
2785 }
2786 return 0;
2787fail_cmd:
2788 return -EINVAL;
2789}
2790
2791static void q6asm_reset_buf_state(struct audio_client *ac)
2792{
2793 int cnt = 0;
2794 int loopcnt = 0;
2795 struct audio_port_data *port = NULL;
2796
2797 if (ac->io_mode == SYNC_IO_MODE) {
2798 mutex_lock(&ac->cmd_lock);
2799 for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
2800 port = &ac->port[loopcnt];
2801 cnt = port->max_buf_cnt - 1;
2802 port->dsp_buf = 0;
2803 port->cpu_buf = 0;
2804 while (cnt >= 0) {
2805 if (!port->buf)
2806 continue;
2807 port->buf[cnt].used = 1;
2808 cnt--;
2809 }
2810 }
2811 mutex_unlock(&ac->cmd_lock);
2812 }
2813}
2814
2815int q6asm_reg_tx_overflow(struct audio_client *ac, uint16_t enable)
2816{
2817 struct asm_stream_cmd_reg_tx_overflow_event tx_overflow;
2818 int rc;
2819
2820 if (!ac || ac->apr == NULL) {
2821 pr_err("APR handle NULL\n");
2822 return -EINVAL;
2823 }
2824 pr_debug("%s:session[%d]enable[%d]\n", __func__,
2825 ac->session, enable);
2826 q6asm_add_hdr(ac, &tx_overflow.hdr, sizeof(tx_overflow), TRUE);
2827
2828 tx_overflow.hdr.opcode = \
2829 ASM_SESSION_CMD_REGISTER_FOR_TX_OVERFLOW_EVENTS;
2830 /* tx overflow event: enable */
2831 tx_overflow.enable = enable;
2832
2833 rc = apr_send_pkt(ac->apr, (uint32_t *) &tx_overflow);
2834 if (rc < 0) {
2835 pr_err("tx overflow op[0x%x]rc[%d]\n", \
2836 tx_overflow.hdr.opcode, rc);
2837 goto fail_cmd;
2838 }
2839 rc = wait_event_timeout(ac->cmd_wait,
2840 (atomic_read(&ac->cmd_state) == 0), 5*HZ);
2841 if (!rc) {
2842 pr_err("timeout. waited for tx overflow\n");
2843 goto fail_cmd;
2844 }
2845 return 0;
2846fail_cmd:
2847 return -EINVAL;
2848}
2849
2850#ifdef CONFIG_MSM8X60_RTAC
2851int q6asm_get_apr_service_id(int session_id)
2852{
2853 pr_debug("%s\n", __func__);
2854
2855 if (session_id < 0) {
2856 pr_err("%s: invalid session_id = %d\n", __func__, session_id);
2857 return -EINVAL;
2858 }
2859
2860 return ((struct apr_svc *)session[session_id]->apr)->id;
2861}
2862#endif
2863
2864
2865static int __init q6asm_init(void)
2866{
2867 pr_debug("%s\n", __func__);
2868 init_waitqueue_head(&this_mmap.cmd_wait);
2869 memset(session, 0, sizeof(session));
Rajesha Kini3498c932011-07-19 19:58:27 +05302870#ifdef CONFIG_DEBUG_FS
2871 out_buffer = kmalloc(OUT_BUFFER_SIZE, GFP_KERNEL);
2872 out_dentry = debugfs_create_file("audio_out_latency_measurement_node",\
2873 S_IFREG | S_IRUGO | S_IWUGO,\
2874 NULL, NULL, &audio_output_latency_debug_fops);
2875 if (IS_ERR(out_dentry))
2876 pr_err("debugfs_create_file failed\n");
2877 in_buffer = kmalloc(IN_BUFFER_SIZE, GFP_KERNEL);
2878 in_dentry = debugfs_create_file("audio_in_latency_measurement_node",\
2879 S_IFREG | S_IRUGO | S_IWUGO,\
2880 NULL, NULL, &audio_input_latency_debug_fops);
2881 if (IS_ERR(in_dentry))
2882 pr_err("debugfs_create_file failed\n");
2883#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002884 return 0;
2885}
2886
2887device_initcall(q6asm_init);