blob: 6468e93f423b2b9f06ebbe69b7ed51a49589a153 [file] [log] [blame]
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002/* audio_pcm.c - pcm audio decoder driver
3 *
Manish Dewangana4f1df02012-02-08 17:06:54 +05304 * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005 *
6 * Based on the mp3 decoder driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
7 *
8 * Copyright (C) 2008 Google, Inc.
9 * Copyright (C) 2008 HTC Corporation
10 *
11 * All source code in this file is licensed under the following license except
12 * where indicated.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License version 2 as published
16 * by the Free Software Foundation.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 *
22 * See the GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, you can find it at http://www.fsf.org
25 */
26
Santosh Mardi0be3b8e2011-07-06 10:00:21 +053027#include <asm/atomic.h>
28#include <asm/ioctls.h>
29
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070030#include <linux/module.h>
31#include <linux/fs.h>
32#include <linux/miscdevice.h>
33#include <linux/uaccess.h>
34#include <linux/kthread.h>
35#include <linux/wait.h>
36#include <linux/dma-mapping.h>
37#include <linux/debugfs.h>
38#include <linux/delay.h>
39#include <linux/earlysuspend.h>
40#include <linux/list.h>
41#include <linux/android_pmem.h>
42#include <linux/slab.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070043#include <linux/msm_audio.h>
44
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045
Santosh Mardi0be3b8e2011-07-06 10:00:21 +053046#include <mach/msm_adsp.h>
47#include <mach/iommu.h>
48#include <mach/iommu_domains.h>
49#include <mach/msm_subsystem_map.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070050#include <mach/qdsp5/qdsp5audppcmdi.h>
51#include <mach/qdsp5/qdsp5audppmsg.h>
52#include <mach/qdsp5/qdsp5audplaycmdi.h>
53#include <mach/qdsp5/qdsp5audplaymsg.h>
54#include <mach/qdsp5/qdsp5rmtcmdi.h>
55#include <mach/debug_mm.h>
Santosh Mardi0be3b8e2011-07-06 10:00:21 +053056#include <linux/memory_alloc.h>
57#include <mach/msm_memtypes.h>
58
59#include "audmgr.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070060
61/* for queue ids - should be relative to module number*/
62#include "adsp.h"
63
64#define ADRV_STATUS_AIO_INTF 0x00000001
65#define ADRV_STATUS_OBUF_GIVEN 0x00000002
66#define ADRV_STATUS_IBUF_GIVEN 0x00000004
67#define ADRV_STATUS_FSYNC 0x00000008
68
69/* Size must be power of 2 */
70#define BUFSZ_MAX 32768
71#define BUFSZ_MIN 4096
72#define DMASZ_MAX (BUFSZ_MAX * 2)
73#define DMASZ_MIN (BUFSZ_MIN * 2)
74
75#define AUDDEC_DEC_PCM 0
76
77/* Decoder status received from AUDPPTASK */
78#define AUDPP_DEC_STATUS_SLEEP 0
79#define AUDPP_DEC_STATUS_INIT 1
80#define AUDPP_DEC_STATUS_CFG 2
81#define AUDPP_DEC_STATUS_PLAY 3
82
83#define AUDPCM_EVENT_NUM 10 /* Default number of pre-allocated event packets */
84
85#define __CONTAINS(r, v, l) ({ \
86 typeof(r) __r = r; \
87 typeof(v) __v = v; \
88 typeof(v) __e = __v + l; \
89 int res = ((__v >= __r->vaddr) && \
90 (__e <= __r->vaddr + __r->len)); \
91 res; \
92})
93
94#define CONTAINS(r1, r2) ({ \
95 typeof(r2) __r2 = r2; \
96 __CONTAINS(r1, __r2->vaddr, __r2->len); \
97})
98
99#define IN_RANGE(r, v) ({ \
100 typeof(r) __r = r; \
101 typeof(v) __vv = v; \
102 int res = ((__vv >= __r->vaddr) && \
103 (__vv < (__r->vaddr + __r->len))); \
104 res; \
105})
106
107#define OVERLAPS(r1, r2) ({ \
108 typeof(r1) __r1 = r1; \
109 typeof(r2) __r2 = r2; \
110 typeof(__r2->vaddr) __v = __r2->vaddr; \
111 typeof(__v) __e = __v + __r2->len - 1; \
112 int res = (IN_RANGE(__r1, __v) || IN_RANGE(__r1, __e)); \
113 res; \
114})
115
116struct audio;
117
118struct buffer {
119 void *data;
120 unsigned size;
121 unsigned used; /* Input usage actual DSP produced PCM size */
122 unsigned addr;
123};
124
125#ifdef CONFIG_HAS_EARLYSUSPEND
126struct audpcm_suspend_ctl {
127 struct early_suspend node;
128 struct audio *audio;
129};
130#endif
131
132struct audpcm_event {
133 struct list_head list;
134 int event_type;
135 union msm_audio_event_payload payload;
136};
137
138struct audpcm_pmem_region {
139 struct list_head list;
140 struct file *file;
141 int fd;
142 void *vaddr_ref;
143 void *vaddr;
144 unsigned long paddr;
145 unsigned long kvaddr;
146 unsigned long len;
147 unsigned ref_cnt;
148};
149
150struct audpcm_buffer_node {
151 struct list_head list;
152 struct msm_audio_aio_buf buf;
153 unsigned long paddr;
154};
155
156struct audpcm_drv_operations {
157 void (*send_data)(struct audio *, unsigned);
158 void (*out_flush)(struct audio *);
159 int (*fsync)(struct audio *);
160};
161
162struct audio {
163 struct buffer out[2];
164
165 spinlock_t dsp_lock;
166
167 uint8_t out_head;
168 uint8_t out_tail;
169 uint8_t out_needed; /* number of buffers the dsp is waiting for */
170 unsigned out_dma_sz;
171 struct list_head out_queue; /* queue to retain output buffers */
172 atomic_t out_bytes;
173
174 struct mutex lock;
175 struct mutex write_lock;
176 wait_queue_head_t write_wait;
177
178 struct msm_adsp_module *audplay;
179
180 /* configuration to use on next enable */
181 uint32_t out_sample_rate;
182 uint32_t out_channel_mode;
183 uint32_t out_bits; /* bits per sample */
184
185 struct audmgr audmgr;
186
187 /* data allocated for various buffers */
188 char *data;
189 int32_t phys;
Santosh Mardi0be3b8e2011-07-06 10:00:21 +0530190 struct msm_mapped_buffer *map_v_write;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700191
192 uint32_t drv_status;
193 int wflush; /* Write flush */
194 int opened;
195 int enabled;
196 int running;
197 int stopped; /* set when stopped, cleared on flush */
198 int teos; /* valid only if tunnel mode & no data left for decoder */
199 int rmt_resource_released;
200 enum msm_aud_decoder_state dec_state; /* Represents decoder state */
201 int reserved; /* A byte is being reserved */
202 char rsv_byte; /* Handle odd length user data */
203
204 const char *module_name;
205 unsigned queue_id;
206
207 unsigned volume;
208
209 uint16_t dec_id;
210
211#ifdef CONFIG_HAS_EARLYSUSPEND
212 struct audpcm_suspend_ctl suspend_ctl;
213#endif
214
215#ifdef CONFIG_DEBUG_FS
216 struct dentry *dentry;
217#endif
218 wait_queue_head_t wait;
219 struct list_head free_event_queue;
220 struct list_head event_queue;
221 wait_queue_head_t event_wait;
222 spinlock_t event_queue_lock;
223 struct mutex get_event_lock;
224 int event_abort;
225
226 struct list_head pmem_region_queue;
227 struct audpcm_drv_operations drv_ops;
228};
229
230static int auddec_dsp_config(struct audio *audio, int enable);
231static void audpp_cmd_cfg_adec_params(struct audio *audio);
232static void audplay_send_data(struct audio *audio, unsigned needed);
233static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
234static void audpcm_post_event(struct audio *audio, int type,
235 union msm_audio_event_payload payload);
236static unsigned long audpcm_pmem_fixup(struct audio *audio, void *addr,
237 unsigned long len, int ref_up);
238
239static int rmt_put_resource(struct audio *audio)
240{
241 struct aud_codec_config_cmd cmd;
242 unsigned short client_idx;
243
244 cmd.cmd_id = RM_CMD_AUD_CODEC_CFG;
245 cmd.client_id = RM_AUD_CLIENT_ID;
246 cmd.task_id = audio->dec_id;
247 cmd.enable = RMT_DISABLE;
248 cmd.dec_type = AUDDEC_DEC_PCM;
249 client_idx = ((cmd.client_id << 8) | cmd.task_id);
250
251 return put_adsp_resource(client_idx, &cmd, sizeof(cmd));
252}
253
254static int rmt_get_resource(struct audio *audio)
255{
256 struct aud_codec_config_cmd cmd;
257 unsigned short client_idx;
258
259 cmd.cmd_id = RM_CMD_AUD_CODEC_CFG;
260 cmd.client_id = RM_AUD_CLIENT_ID;
261 cmd.task_id = audio->dec_id;
262 cmd.enable = RMT_ENABLE;
263 cmd.dec_type = AUDDEC_DEC_PCM;
264 client_idx = ((cmd.client_id << 8) | cmd.task_id);
265
266 return get_adsp_resource(client_idx, &cmd, sizeof(cmd));
267}
268
269/* must be called with audio->lock held */
270static int audio_enable(struct audio *audio)
271{
272 struct audmgr_config cfg;
273 int rc;
274
275 MM_DBG("\n"); /* Macro prints the file name and function */
276 if (audio->enabled)
277 return 0;
278
279 if (audio->rmt_resource_released == 1) {
280 audio->rmt_resource_released = 0;
281 rc = rmt_get_resource(audio);
282 if (rc) {
283 MM_ERR("ADSP resources are not available for PCM \
284 session 0x%08x on decoder: %d\n Ignoring \
285 error and going ahead with the playback\n",
286 (int)audio, audio->dec_id);
287 }
288 }
289
290 audio->dec_state = MSM_AUD_DECODER_STATE_NONE;
291 audio->out_tail = 0;
292 audio->out_needed = 0;
293
294 cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
295 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
296 cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
297 cfg.codec = RPC_AUD_DEF_CODEC_PCM;
298 cfg.snd_method = RPC_SND_METHOD_MIDI;
299
300 rc = audmgr_enable(&audio->audmgr, &cfg);
301 if (rc < 0)
302 return rc;
303
304 if (msm_adsp_enable(audio->audplay)) {
305 MM_ERR("msm_adsp_enable(audplay) failed\n");
306 audmgr_disable(&audio->audmgr);
307 return -ENODEV;
308 }
309
310 if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
311 MM_ERR("audpp_enable() failed\n");
312 msm_adsp_disable(audio->audplay);
313 audmgr_disable(&audio->audmgr);
314 return -ENODEV;
315 }
316
317 audio->enabled = 1;
318 return 0;
319}
320
321/* must be called with audio->lock held */
322static int audio_disable(struct audio *audio)
323{
324 int rc = 0;
325 MM_DBG("\n"); /* Macro prints the file name and function */
326 if (audio->enabled) {
327 audio->enabled = 0;
328 audio->dec_state = MSM_AUD_DECODER_STATE_NONE;
329 auddec_dsp_config(audio, 0);
330 rc = wait_event_interruptible_timeout(audio->wait,
331 audio->dec_state != MSM_AUD_DECODER_STATE_NONE,
332 msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS));
333 if (rc == 0)
334 rc = -ETIMEDOUT;
335 else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE)
336 rc = -EFAULT;
337 else
338 rc = 0;
Manish Dewangan89a9f232012-02-09 17:14:40 +0530339 audio->stopped = 1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700340 wake_up(&audio->write_wait);
341 msm_adsp_disable(audio->audplay);
342 audpp_disable(audio->dec_id, audio);
343 audmgr_disable(&audio->audmgr);
344 audio->out_needed = 0;
345 rmt_put_resource(audio);
346 audio->rmt_resource_released = 1;
347 }
348 return rc;
349}
350
351/* ------------------- dsp --------------------- */
352static void audplay_dsp_event(void *data, unsigned id, size_t len,
353 void (*getevent) (void *ptr, size_t len))
354{
355 struct audio *audio = data;
356 uint32_t msg[28];
357 getevent(msg, sizeof(msg));
358
359 MM_DBG("msg_id=%x\n", id);
360
361 switch (id) {
362 case AUDPLAY_MSG_DEC_NEEDS_DATA:
363 audio->drv_ops.send_data(audio, 1);
364 break;
365 case ADSP_MESSAGE_ID:
366 MM_DBG("Received ADSP event: module enable(audplaytask)\n");
367 break;
368 default:
369 MM_ERR("unexpected message from decoder \n");
370 break;
371 }
372}
373
374static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
375{
376 struct audio *audio = private;
377
378 switch (id) {
379 case AUDPP_MSG_STATUS_MSG:{
380 unsigned status = msg[1];
381
382 switch (status) {
383 case AUDPP_DEC_STATUS_SLEEP: {
384 uint16_t reason = msg[2];
385 MM_DBG("decoder status: sleep reason = \
386 0x%04x\n", reason);
387 if ((reason == AUDPP_MSG_REASON_MEM)
388 || (reason ==
389 AUDPP_MSG_REASON_NODECODER)) {
390 audio->dec_state =
391 MSM_AUD_DECODER_STATE_FAILURE;
392 wake_up(&audio->wait);
393 } else if (reason == AUDPP_MSG_REASON_NONE) {
394 /* decoder is in disable state */
395 audio->dec_state =
396 MSM_AUD_DECODER_STATE_CLOSE;
397 wake_up(&audio->wait);
398 }
399 break;
400 }
401 case AUDPP_DEC_STATUS_INIT:
402 MM_DBG("decoder status: init\n");
403 audpp_cmd_cfg_adec_params(audio);
404 break;
405
406 case AUDPP_DEC_STATUS_CFG:
407 MM_DBG("decoder status: cfg \n");
408 break;
409 case AUDPP_DEC_STATUS_PLAY:
410 MM_DBG("decoder status: play \n");
411 audio->dec_state =
412 MSM_AUD_DECODER_STATE_SUCCESS;
413 wake_up(&audio->wait);
414 break;
415 default:
416 MM_ERR("unknown decoder status \n");
417 break;
418 }
419 break;
420 }
421 case AUDPP_MSG_CFG_MSG:
422 if (msg[0] == AUDPP_MSG_ENA_ENA) {
423 MM_DBG("CFG_MSG ENABLE\n");
424 auddec_dsp_config(audio, 1);
425 audio->out_needed = 0;
426 audio->running = 1;
427 audpp_set_volume_and_pan(audio->dec_id, audio->volume,
428 0);
429 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
430 MM_DBG("CFG_MSG DISABLE\n");
431 audio->running = 0;
432 } else {
433 MM_ERR("CFG_MSG %d?\n", msg[0]);
434 }
435 break;
436 case AUDPP_MSG_FLUSH_ACK:
437 MM_DBG("FLUSH_ACK\n");
438 audio->wflush = 0;
439 wake_up(&audio->write_wait);
440 break;
441
442 case AUDPP_MSG_PCMDMAMISSED:
443 MM_DBG("PCMDMAMISSED\n");
444 audio->teos = 1;
445 wake_up(&audio->write_wait);
446 break;
447
448 default:
449 MM_ERR("UNKNOWN (%d)\n", id);
450 }
451
452}
453
454
455struct msm_adsp_ops audpcmdec_adsp_ops = {
456 .event = audplay_dsp_event,
457};
458
459
460#define audplay_send_queue0(audio, cmd, len) \
461 msm_adsp_write(audio->audplay, audio->queue_id, \
462 cmd, len)
463
464static int auddec_dsp_config(struct audio *audio, int enable)
465{
466 u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)];
467
468 memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd));
469
470 cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE;
471 if (enable)
472 cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC |
473 AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_PCM;
474 else
475 cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC |
476 AUDPP_CMD_DIS_DEC_V;
477
478 return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd));
479}
480
481static void audpp_cmd_cfg_adec_params(struct audio *audio)
482{
483 audpp_cmd_cfg_adec_params_wav cmd;
484
485 memset(&cmd, 0, sizeof(cmd));
486 cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
487 cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_WAV_LEN;
488 cmd.common.dec_id = audio->dec_id;
489 cmd.common.input_sampling_frequency = audio->out_sample_rate;
490 cmd.stereo_cfg = audio->out_channel_mode;
491 cmd.pcm_width = audio->out_bits;
492 cmd.sign = 0;
493 audpp_send_queue2(&cmd, sizeof(cmd));
494}
495
496static int audplay_dsp_send_data_avail(struct audio *audio,
497 unsigned idx, unsigned len)
498{
499 audplay_cmd_bitstream_data_avail cmd;
500
501 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
502 cmd.decoder_id = audio->dec_id;
503 cmd.buf_ptr = audio->out[idx].addr;
504 cmd.buf_size = len/2;
505 cmd.partition_number = 0;
506 /* complete writes to the input buffer */
507 wmb();
508 return audplay_send_queue0(audio, &cmd, sizeof(cmd));
509}
510
511static void audpcm_async_send_data(struct audio *audio, unsigned needed)
512{
513 unsigned long flags;
514
515 if (!audio->running)
516 return;
517
518 spin_lock_irqsave(&audio->dsp_lock, flags);
519
520 if (needed && !audio->wflush) {
521 audio->out_needed = 1;
522 if (audio->drv_status & ADRV_STATUS_OBUF_GIVEN) {
523 /* pop one node out of queue */
524 union msm_audio_event_payload payload;
525 struct audpcm_buffer_node *used_buf;
526
527 MM_DBG("consumed\n");
528
529 BUG_ON(list_empty(&audio->out_queue));
530 used_buf = list_first_entry(&audio->out_queue,
531 struct audpcm_buffer_node, list);
532 list_del(&used_buf->list);
533 payload.aio_buf = used_buf->buf;
534 audpcm_post_event(audio, AUDIO_EVENT_WRITE_DONE,
535 payload);
536 kfree(used_buf);
537 audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN;
538 }
539 }
540 if (audio->out_needed) {
541 struct audpcm_buffer_node *next_buf;
542 audplay_cmd_bitstream_data_avail cmd;
543 if (!list_empty(&audio->out_queue)) {
544 next_buf = list_first_entry(&audio->out_queue,
545 struct audpcm_buffer_node, list);
546 MM_DBG("next_buf %p\n", next_buf);
547 if (next_buf) {
548 MM_DBG("next buf phy %lx len %d\n",
549 next_buf->paddr, next_buf->buf.data_len);
550
551 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
552 if (next_buf->buf.data_len)
553 cmd.decoder_id = audio->dec_id;
554 else {
555 cmd.decoder_id = -1;
556 MM_DBG("input EOS signaled\n");
557 }
558 cmd.buf_ptr = (unsigned) next_buf->paddr;
559 cmd.buf_size = next_buf->buf.data_len >> 1;
560 cmd.partition_number = 0;
561 /* complete writes to the input buffer */
562 wmb();
563 audplay_send_queue0(audio, &cmd, sizeof(cmd));
564 audio->out_needed = 0;
565 audio->drv_status |= ADRV_STATUS_OBUF_GIVEN;
566 }
567 }
568 }
569 spin_unlock_irqrestore(&audio->dsp_lock, flags);
570}
571
572static void audplay_send_data(struct audio *audio, unsigned needed)
573{
574 struct buffer *frame;
575 unsigned long flags;
576
577 if (!audio->running)
578 return;
579
580 spin_lock_irqsave(&audio->dsp_lock, flags);
581
582 if (needed && !audio->wflush) {
583 /* We were called from the callback because the DSP
584 * requested more data. Note that the DSP does want
585 * more data, and if a buffer was in-flight, mark it
586 * as available (since the DSP must now be done with
587 * it).
588 */
589 audio->out_needed = 1;
590 frame = audio->out + audio->out_tail;
591 if (frame->used == 0xffffffff) {
592 MM_DBG("frame %d free\n", audio->out_tail);
593 frame->used = 0;
594 audio->out_tail ^= 1;
595 wake_up(&audio->write_wait);
596 }
597 }
598
599 if (audio->out_needed) {
600 /* If the DSP currently wants data and we have a
601 * buffer available, we will send it and reset
602 * the needed flag. We'll mark the buffer as in-flight
603 * so that it won't be recycled until the next buffer
604 * is requested
605 */
606
607 frame = audio->out + audio->out_tail;
608 if (frame->used) {
609 BUG_ON(frame->used == 0xffffffff);
610 MM_DBG("frame %d busy\n", audio->out_tail);
611 audplay_dsp_send_data_avail(audio, audio->out_tail,
612 frame->used);
613 frame->used = 0xffffffff;
614 audio->out_needed = 0;
615 }
616 }
617 spin_unlock_irqrestore(&audio->dsp_lock, flags);
618}
619
620/* ------------------- device --------------------- */
621static void audpcm_async_flush(struct audio *audio)
622{
623 struct audpcm_buffer_node *buf_node;
624 struct list_head *ptr, *next;
625 union msm_audio_event_payload payload;
626
627 MM_DBG("\n"); /* Macro prints the file name and function */
628 list_for_each_safe(ptr, next, &audio->out_queue) {
629 buf_node = list_entry(ptr, struct audpcm_buffer_node, list);
630 list_del(&buf_node->list);
631 payload.aio_buf = buf_node->buf;
632 audpcm_post_event(audio, AUDIO_EVENT_WRITE_DONE,
633 payload);
634 kfree(buf_node);
635 }
636 audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN;
637 audio->out_needed = 0;
638 atomic_set(&audio->out_bytes, 0);
639}
640
641static void audio_flush(struct audio *audio)
642{
Manish Dewangana4f1df02012-02-08 17:06:54 +0530643 unsigned long flags;
644
645 spin_lock_irqsave(&audio->dsp_lock, flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700646 audio->out[0].used = 0;
647 audio->out[1].used = 0;
648 audio->out_head = 0;
649 audio->out_tail = 0;
650 audio->reserved = 0;
651 audio->out_needed = 0;
Manish Dewangana4f1df02012-02-08 17:06:54 +0530652 spin_unlock_irqrestore(&audio->dsp_lock, flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700653 atomic_set(&audio->out_bytes, 0);
654}
655
656static void audio_ioport_reset(struct audio *audio)
657{
658 if (audio->drv_status & ADRV_STATUS_AIO_INTF) {
659 /* If fsync is in progress, make sure
660 * return value of fsync indicates
661 * abort due to flush
662 */
663 if (audio->drv_status & ADRV_STATUS_FSYNC) {
664 MM_DBG("fsync in progress\n");
665 wake_up(&audio->write_wait);
666 mutex_lock(&audio->write_lock);
667 audio->drv_ops.out_flush(audio);
668 mutex_unlock(&audio->write_lock);
669 } else
670 audio->drv_ops.out_flush(audio);
671 } else {
672 /* Make sure read/write thread are free from
673 * sleep and knowing that system is not able
674 * to process io request at the moment
675 */
676 wake_up(&audio->write_wait);
677 mutex_lock(&audio->write_lock);
678 audio->drv_ops.out_flush(audio);
679 mutex_unlock(&audio->write_lock);
680 }
681}
682
683static int audpcm_events_pending(struct audio *audio)
684{
685 unsigned long flags;
686 int empty;
687
688 spin_lock_irqsave(&audio->event_queue_lock, flags);
689 empty = !list_empty(&audio->event_queue);
690 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
691 return empty || audio->event_abort;
692}
693
694static void audpcm_reset_event_queue(struct audio *audio)
695{
696 unsigned long flags;
697 struct audpcm_event *drv_evt;
698 struct list_head *ptr, *next;
699
700 spin_lock_irqsave(&audio->event_queue_lock, flags);
701 list_for_each_safe(ptr, next, &audio->event_queue) {
702 drv_evt = list_first_entry(&audio->event_queue,
703 struct audpcm_event, list);
704 list_del(&drv_evt->list);
705 kfree(drv_evt);
706 }
707 list_for_each_safe(ptr, next, &audio->free_event_queue) {
708 drv_evt = list_first_entry(&audio->free_event_queue,
709 struct audpcm_event, list);
710 list_del(&drv_evt->list);
711 kfree(drv_evt);
712 }
713 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
714
715 return;
716}
717
718static long audpcm_process_event_req(struct audio *audio, void __user *arg)
719{
720 long rc;
721 struct msm_audio_event usr_evt;
722 struct audpcm_event *drv_evt = NULL;
723 int timeout;
724 unsigned long flags;
725
726 if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event)))
727 return -EFAULT;
728
729 timeout = (int) usr_evt.timeout_ms;
730
731 if (timeout > 0) {
732 rc = wait_event_interruptible_timeout(
733 audio->event_wait, audpcm_events_pending(audio),
734 msecs_to_jiffies(timeout));
735 if (rc == 0)
736 return -ETIMEDOUT;
737 } else {
738 rc = wait_event_interruptible(
739 audio->event_wait, audpcm_events_pending(audio));
740 }
741
742 if (rc < 0)
743 return rc;
744
745 if (audio->event_abort) {
746 audio->event_abort = 0;
747 return -ENODEV;
748 }
749
750 spin_lock_irqsave(&audio->event_queue_lock, flags);
751 if (!list_empty(&audio->event_queue)) {
752 drv_evt = list_first_entry(&audio->event_queue,
753 struct audpcm_event, list);
754 list_del(&drv_evt->list);
755 }
756 if (drv_evt) {
757 usr_evt.event_type = drv_evt->event_type;
758 usr_evt.event_payload = drv_evt->payload;
759 list_add_tail(&drv_evt->list, &audio->free_event_queue);
760 } else
761 rc = -1;
762 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
763
764 if (drv_evt && drv_evt->event_type == AUDIO_EVENT_WRITE_DONE) {
765 mutex_lock(&audio->lock);
766 audpcm_pmem_fixup(audio, drv_evt->payload.aio_buf.buf_addr,
767 drv_evt->payload.aio_buf.buf_len, 0);
768 mutex_unlock(&audio->lock);
769 }
770 if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt)))
771 rc = -EFAULT;
772
773 return rc;
774}
775
776static int audpcm_pmem_check(struct audio *audio,
777 void *vaddr, unsigned long len)
778{
779 struct audpcm_pmem_region *region_elt;
780 struct audpcm_pmem_region t = { .vaddr = vaddr, .len = len };
781
782 list_for_each_entry(region_elt, &audio->pmem_region_queue, list) {
783 if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
784 OVERLAPS(region_elt, &t)) {
785 MM_ERR("region (vaddr %p len %ld)"
786 " clashes with registered region"
787 " (vaddr %p paddr %p len %ld)\n",
788 vaddr, len,
789 region_elt->vaddr,
790 (void *)region_elt->paddr,
791 region_elt->len);
792 return -EINVAL;
793 }
794 }
795
796 return 0;
797}
798
799static int audpcm_pmem_add(struct audio *audio,
800 struct msm_audio_pmem_info *info)
801{
802 unsigned long paddr, kvaddr, len;
803 struct file *file;
804 struct audpcm_pmem_region *region;
805 struct vm_area_struct *vma;
806 int rc = -EINVAL;
807
808 MM_DBG("\n"); /* Macro prints the file name and function */
809 region = kmalloc(sizeof(*region), GFP_KERNEL);
810 if (!region)
811 return -ENOMEM;
812
813 if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
814 kfree(region);
815 return -EINVAL;
816 }
817
818 vma = find_vma_intersection(current->active_mm,
819 (unsigned long) info->vaddr, (unsigned long) info->vaddr+1);
820
821 if (vma && ((vma->vm_end - vma->vm_start) == len)) {
822 rc = audpcm_pmem_check(audio, (void *) vma->vm_start, len);
823 if (rc < 0) {
824 put_pmem_file(file);
825 kfree(region);
826 return rc;
827 }
828 region->vaddr = (void *) vma->vm_start;
829 region->vaddr_ref = info->vaddr;
830 MM_DBG("Valid VMA region vma->vm_start = 0x%8x \
831 vma->vm_end = 0x%8x\n", (int) vma->vm_start,
832 (int) vma->vm_end);
833 } else {
834 MM_ERR("No valid VMA region found\n");
835 put_pmem_file(file);
836 kfree(region);
837 return rc;
838 }
839 region->fd = info->fd;
840 region->paddr = paddr;
841 region->kvaddr = kvaddr;
842 region->len = len;
843 region->file = file;
844 region->ref_cnt = 0;
845 MM_DBG("add region paddr %lx vaddr %p, len %lu\n", region->paddr,
846 region->vaddr, region->len);
847 list_add_tail(&region->list, &audio->pmem_region_queue);
848 return rc;
849}
850
851static int audpcm_pmem_remove(struct audio *audio,
852 struct msm_audio_pmem_info *info)
853{
854 struct audpcm_pmem_region *region;
855 struct list_head *ptr, *next;
856 int rc = -EINVAL;
857
858 MM_DBG("info fd %d vaddr %p\n", info->fd, info->vaddr);
859
860 list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
861 region = list_entry(ptr, struct audpcm_pmem_region, list);
862
863 if ((region->fd == info->fd) &&
864 (region->vaddr_ref == info->vaddr)) {
865 if (region->ref_cnt) {
866 MM_DBG("region %p in use ref_cnt %d\n",
867 region, region->ref_cnt);
868 break;
869 }
870 MM_DBG("remove region fd %d vaddr %p \n", info->fd,
871 info->vaddr);
872 list_del(&region->list);
873 put_pmem_file(region->file);
874 kfree(region);
875 rc = 0;
876 break;
877 }
878 }
879
880 return rc;
881}
882
883static int audpcm_pmem_lookup_vaddr(struct audio *audio, void *addr,
884 unsigned long len, struct audpcm_pmem_region **region)
885{
886 struct audpcm_pmem_region *region_elt;
887
888 int match_count = 0;
889
890 *region = NULL;
891
892 /* returns physical address or zero */
893 list_for_each_entry(region_elt, &audio->pmem_region_queue,
894 list) {
895 if (addr >= region_elt->vaddr &&
896 addr < region_elt->vaddr + region_elt->len &&
897 addr + len <= region_elt->vaddr + region_elt->len) {
898 /* offset since we could pass vaddr inside a registerd
899 * pmem buffer
900 */
901 match_count++;
902 if (!*region)
903 *region = region_elt;
904 }
905 }
906
907 if (match_count > 1) {
908 MM_ERR("multiple hits for vaddr %p, len %ld\n", addr, len);
909 list_for_each_entry(region_elt,
910 &audio->pmem_region_queue, list) {
911 if (addr >= region_elt->vaddr &&
912 addr < region_elt->vaddr + region_elt->len &&
913 addr + len <= region_elt->vaddr + region_elt->len)
914 MM_ERR("\t%p, %ld --> %p\n", region_elt->vaddr,
915 region_elt->len,
916 (void *)region_elt->paddr);
917 }
918 }
919
920 return *region ? 0 : -1;
921}
922
923static unsigned long audpcm_pmem_fixup(struct audio *audio, void *addr,
924 unsigned long len, int ref_up)
925{
926 struct audpcm_pmem_region *region;
927 unsigned long paddr;
928 int ret;
929
930 ret = audpcm_pmem_lookup_vaddr(audio, addr, len, &region);
931 if (ret) {
932 MM_ERR("lookup (%p, %ld) failed\n", addr, len);
933 return 0;
934 }
935 if (ref_up)
936 region->ref_cnt++;
937 else
938 region->ref_cnt--;
939 MM_DBG("found region %p ref_cnt %d\n", region, region->ref_cnt);
940 paddr = region->paddr + (addr - region->vaddr);
941 return paddr;
942}
943
944/* audio -> lock must be held at this point */
945static int audpcm_aio_buf_add(struct audio *audio, unsigned dir,
946 void __user *arg)
947{
948 unsigned long flags;
949 struct audpcm_buffer_node *buf_node;
950
951 buf_node = kmalloc(sizeof(*buf_node), GFP_KERNEL);
952
953 if (!buf_node)
954 return -ENOMEM;
955
956 if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) {
957 kfree(buf_node);
958 return -EFAULT;
959 }
960
961 MM_DBG("node %p dir %x buf_addr %p buf_len %d data_len %d\n",
962 buf_node, dir, buf_node->buf.buf_addr,
963 buf_node->buf.buf_len, buf_node->buf.data_len);
964
965 buf_node->paddr = audpcm_pmem_fixup(
966 audio, buf_node->buf.buf_addr,
967 buf_node->buf.buf_len, 1);
968 if (dir) {
969 /* write */
970 if (!buf_node->paddr ||
971 (buf_node->paddr & 0x1) ||
972 (buf_node->buf.data_len & 0x1) ||
973 (!buf_node->buf.data_len)) {
974 kfree(buf_node);
975 return -EINVAL;
976 }
977 spin_lock_irqsave(&audio->dsp_lock, flags);
978 list_add_tail(&buf_node->list, &audio->out_queue);
979 spin_unlock_irqrestore(&audio->dsp_lock, flags);
980 audio->drv_ops.send_data(audio, 0);
981 }
982
983 MM_DBG("Add buf_node %p paddr %lx\n", buf_node, buf_node->paddr);
984
985 return 0;
986}
987
988static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
989{
990 struct audio *audio = file->private_data;
991 int rc = 0;
992
993 MM_DBG("cmd = %d\n", cmd);
994
995 if (cmd == AUDIO_GET_STATS) {
996 struct msm_audio_stats stats;
997 stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
998 stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
999 if (copy_to_user((void *) arg, &stats, sizeof(stats)))
1000 return -EFAULT;
1001 return 0;
1002 }
1003 if (cmd == AUDIO_SET_VOLUME) {
1004 unsigned long flags;
1005 spin_lock_irqsave(&audio->dsp_lock, flags);
1006 audio->volume = arg;
1007 if (audio->running)
1008 audpp_set_volume_and_pan(audio->dec_id, arg, 0);
1009 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1010 return 0;
1011 }
1012 if (cmd == AUDIO_GET_EVENT) {
1013 MM_DBG("AUDIO_GET_EVENT\n");
1014 if (mutex_trylock(&audio->get_event_lock)) {
1015 rc = audpcm_process_event_req(audio,
1016 (void __user *) arg);
1017 mutex_unlock(&audio->get_event_lock);
1018 } else
1019 rc = -EBUSY;
1020 return rc;
1021 }
1022
1023 if (cmd == AUDIO_ABORT_GET_EVENT) {
1024 audio->event_abort = 1;
1025 wake_up(&audio->event_wait);
1026 return 0;
1027 }
1028
1029 mutex_lock(&audio->lock);
1030 switch (cmd) {
1031 case AUDIO_START:
1032 MM_DBG("AUDIO_START\n");
1033 rc = audio_enable(audio);
1034 if (!rc) {
1035 rc = wait_event_interruptible_timeout(audio->wait,
1036 audio->dec_state != MSM_AUD_DECODER_STATE_NONE,
1037 msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS));
1038 MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc);
1039
1040 if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS)
1041 rc = -ENODEV;
1042 else
1043 rc = 0;
1044 }
1045 break;
1046 case AUDIO_STOP:
1047 MM_DBG("AUDIO_STOP\n");
1048 rc = audio_disable(audio);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001049 audio_ioport_reset(audio);
1050 audio->stopped = 0;
1051 break;
1052 case AUDIO_FLUSH:
1053 MM_DBG("AUDIO_FLUSH\n");
1054 audio->wflush = 1;
1055 audio_ioport_reset(audio);
1056 if (audio->running) {
1057 audpp_flush(audio->dec_id);
1058 rc = wait_event_interruptible(audio->write_wait,
1059 !audio->wflush);
1060 if (rc < 0) {
1061 MM_ERR("AUDIO_FLUSH interrupted\n");
1062 rc = -EINTR;
1063 }
1064 } else {
1065 audio->wflush = 0;
1066 }
1067 break;
1068
1069 case AUDIO_SET_CONFIG: {
1070 struct msm_audio_config config;
1071 if (copy_from_user(&config, (void *) arg, sizeof(config))) {
1072 rc = -EFAULT;
1073 break;
1074 }
1075 if (config.channel_count == 1) {
1076 config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
1077 } else if (config.channel_count == 2) {
1078 config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V;
1079 } else {
1080 rc = -EINVAL;
1081 break;
1082 }
1083 if (config.bits == 8)
1084 config.bits = AUDPP_CMD_WAV_PCM_WIDTH_8;
1085 else if (config.bits == 16)
1086 config.bits = AUDPP_CMD_WAV_PCM_WIDTH_16;
1087 else if (config.bits == 24)
1088 config.bits = AUDPP_CMD_WAV_PCM_WIDTH_24;
1089 else {
1090 rc = -EINVAL;
1091 break;
1092 }
1093 audio->out_sample_rate = config.sample_rate;
1094 audio->out_channel_mode = config.channel_count;
1095 audio->out_bits = config.bits;
1096 break;
1097 }
1098 case AUDIO_GET_CONFIG: {
1099 struct msm_audio_config config;
1100 config.buffer_size = (audio->out_dma_sz >> 1);
1101 config.buffer_count = 2;
1102 config.sample_rate = audio->out_sample_rate;
1103 if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V)
1104 config.channel_count = 1;
1105 else
1106 config.channel_count = 2;
1107 if (audio->out_bits == AUDPP_CMD_WAV_PCM_WIDTH_8)
1108 config.bits = 8;
1109 else if (audio->out_bits == AUDPP_CMD_WAV_PCM_WIDTH_24)
1110 config.bits = 24;
1111 else
1112 config.bits = 16;
1113 config.unused[0] = 0;
1114 config.unused[1] = 0;
1115
1116 if (copy_to_user((void *) arg, &config, sizeof(config)))
1117 rc = -EFAULT;
1118 else
1119 rc = 0;
1120 break;
1121 }
1122
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301123
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001124 case AUDIO_PAUSE:
1125 MM_DBG("AUDIO_PAUSE %ld\n", arg);
1126 rc = audpp_pause(audio->dec_id, (int) arg);
1127 break;
1128
1129 case AUDIO_REGISTER_PMEM: {
1130 struct msm_audio_pmem_info info;
1131 MM_DBG("AUDIO_REGISTER_PMEM\n");
1132 if (copy_from_user(&info, (void *) arg, sizeof(info)))
1133 rc = -EFAULT;
1134 else
1135 rc = audpcm_pmem_add(audio, &info);
1136 break;
1137 }
1138
1139 case AUDIO_DEREGISTER_PMEM: {
1140 struct msm_audio_pmem_info info;
1141 MM_DBG("AUDIO_DEREGISTER_PMEM\n");
1142 if (copy_from_user(&info, (void *) arg, sizeof(info)))
1143 rc = -EFAULT;
1144 else
1145 rc = audpcm_pmem_remove(audio, &info);
1146 break;
1147 }
1148
1149 case AUDIO_ASYNC_WRITE:
1150 if (audio->drv_status & ADRV_STATUS_FSYNC)
1151 rc = -EBUSY;
1152 else
1153 rc = audpcm_aio_buf_add(audio, 1, (void __user *) arg);
1154 break;
1155
1156 case AUDIO_ASYNC_READ:
1157 MM_ERR("AUDIO_ASYNC_READ not supported\n");
1158 rc = -EPERM;
1159 break;
1160
1161 default:
1162 rc = -EINVAL;
1163 }
1164 mutex_unlock(&audio->lock);
1165 return rc;
1166}
1167
1168/* Only useful in tunnel-mode */
1169int audpcm_async_fsync(struct audio *audio)
1170{
1171 int rc = 0;
1172
1173 MM_DBG("\n"); /* Macro prints the file name and function */
1174
1175 /* Blocking client sends more data */
1176 mutex_lock(&audio->lock);
1177 audio->drv_status |= ADRV_STATUS_FSYNC;
1178 mutex_unlock(&audio->lock);
1179
1180 mutex_lock(&audio->write_lock);
1181 /* pcm dmamiss message is sent continously
1182 * when decoder is starved so no race
1183 * condition concern
1184 */
1185 audio->teos = 0;
1186
1187 rc = wait_event_interruptible(audio->write_wait,
1188 (audio->teos && audio->out_needed &&
1189 list_empty(&audio->out_queue))
1190 || audio->wflush || audio->stopped);
1191
1192 if (audio->stopped || audio->wflush)
1193 rc = -EBUSY;
1194
1195 mutex_unlock(&audio->write_lock);
1196 mutex_lock(&audio->lock);
1197 audio->drv_status &= ~ADRV_STATUS_FSYNC;
1198 mutex_unlock(&audio->lock);
1199
1200 return rc;
1201}
1202
1203int audpcm_sync_fsync(struct audio *audio)
1204{
1205 struct buffer *frame;
1206 int rc = 0;
1207
1208 MM_DBG("\n"); /* Macro prints the file name and function */
1209
1210 mutex_lock(&audio->write_lock);
1211
1212 rc = wait_event_interruptible(audio->write_wait,
1213 (!audio->out[0].used &&
1214 !audio->out[1].used &&
1215 audio->out_needed) || audio->wflush);
1216
1217 if (rc < 0)
1218 goto done;
1219 else if (audio->wflush) {
1220 rc = -EBUSY;
1221 goto done;
1222 }
1223
1224 if (audio->reserved) {
1225 MM_DBG("send reserved byte\n");
1226 frame = audio->out + audio->out_tail;
1227 ((char *) frame->data)[0] = audio->rsv_byte;
1228 ((char *) frame->data)[1] = 0;
1229 frame->used = 2;
1230 audio->drv_ops.send_data(audio, 0);
1231
1232 rc = wait_event_interruptible(audio->write_wait,
1233 (!audio->out[0].used &&
1234 !audio->out[1].used &&
1235 audio->out_needed) || audio->wflush);
1236
1237 if (rc < 0)
1238 goto done;
1239 else if (audio->wflush) {
1240 rc = -EBUSY;
1241 goto done;
1242 }
1243 }
1244
1245 /* pcm dmamiss message is sent continously
1246 * when decoder is starved so no race
1247 * condition concern
1248 */
1249 audio->teos = 0;
1250
1251 rc = wait_event_interruptible(audio->write_wait,
1252 audio->teos || audio->wflush);
1253
1254 if (audio->wflush)
1255 rc = -EBUSY;
1256
1257done:
1258 mutex_unlock(&audio->write_lock);
1259 return rc;
1260}
1261
1262int audpcm_fsync(struct file *file, int datasync)
1263{
1264 struct audio *audio = file->private_data;
1265
1266 if (!audio->running)
1267 return -EINVAL;
1268
1269 return audio->drv_ops.fsync(audio);
1270}
1271
1272static ssize_t audio_write(struct file *file, const char __user *buf,
1273 size_t count, loff_t *pos)
1274{
1275 struct audio *audio = file->private_data;
1276 const char __user *start = buf;
1277 struct buffer *frame;
1278 size_t xfer;
1279 char *cpy_ptr;
1280 int rc = 0;
1281 unsigned dsize;
1282
1283 if (audio->drv_status & ADRV_STATUS_AIO_INTF)
1284 return -EPERM;
1285
1286 MM_DBG("cnt=%d\n", count);
1287
1288 mutex_lock(&audio->write_lock);
1289 while (count > 0) {
1290 frame = audio->out + audio->out_head;
1291 cpy_ptr = frame->data;
1292 dsize = 0;
1293 rc = wait_event_interruptible(audio->write_wait,
1294 (frame->used == 0)
1295 || (audio->stopped)
1296 || (audio->wflush));
1297 if (rc < 0)
1298 break;
1299 if (audio->stopped || audio->wflush) {
1300 rc = -EBUSY;
1301 break;
1302 }
1303
1304 if (audio->reserved) {
1305 MM_DBG("append reserved byte %x\n", audio->rsv_byte);
1306 *cpy_ptr = audio->rsv_byte;
1307 xfer = (count > (frame->size - 1)) ?
1308 frame->size - 1 : count;
1309 cpy_ptr++;
1310 dsize = 1;
1311 audio->reserved = 0;
1312 } else
1313 xfer = (count > frame->size) ? frame->size : count;
1314
1315 if (copy_from_user(cpy_ptr, buf, xfer)) {
1316 rc = -EFAULT;
1317 break;
1318 }
1319
1320 dsize += xfer;
1321 if (dsize & 1) {
1322 audio->rsv_byte = ((char *) frame->data)[dsize - 1];
1323 MM_DBG("odd length buf reserve last byte %x\n",
1324 audio->rsv_byte);
1325 audio->reserved = 1;
1326 dsize--;
1327 }
1328 count -= xfer;
1329 buf += xfer;
1330
1331 if (dsize > 0) {
1332 audio->out_head ^= 1;
1333 frame->used = dsize;
1334 audio->drv_ops.send_data(audio, 0);
1335 }
1336 }
1337 mutex_unlock(&audio->write_lock);
1338 if (buf > start)
1339 return buf - start;
1340
1341 return rc;
1342}
1343
1344static void audpcm_reset_pmem_region(struct audio *audio)
1345{
1346 struct audpcm_pmem_region *region;
1347 struct list_head *ptr, *next;
1348
1349 list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
1350 region = list_entry(ptr, struct audpcm_pmem_region, list);
1351 list_del(&region->list);
1352 put_pmem_file(region->file);
1353 kfree(region);
1354 }
1355
1356 return;
1357}
1358
1359static int audio_release(struct inode *inode, struct file *file)
1360{
1361 struct audio *audio = file->private_data;
1362
1363 MM_DBG("audio instance 0x%08x freeing\n", (int)audio);
1364 mutex_lock(&audio->lock);
1365 audio_disable(audio);
1366 if (audio->rmt_resource_released == 0)
1367 rmt_put_resource(audio);
1368 audio->drv_ops.out_flush(audio);
1369 audpcm_reset_pmem_region(audio);
1370
1371 msm_adsp_put(audio->audplay);
1372 audpp_adec_free(audio->dec_id);
1373#ifdef CONFIG_HAS_EARLYSUSPEND
1374 unregister_early_suspend(&audio->suspend_ctl.node);
1375#endif
1376 audio->opened = 0;
1377 audio->event_abort = 1;
1378 wake_up(&audio->event_wait);
1379 audpcm_reset_event_queue(audio);
1380 MM_DBG("pmem area = 0x%8x\n", (unsigned int)audio->data);
1381 if (audio->data) {
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301382 msm_subsystem_unmap_buffer(audio->map_v_write);
1383 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001384 }
1385 mutex_unlock(&audio->lock);
1386#ifdef CONFIG_DEBUG_FS
1387 if (audio->dentry)
1388 debugfs_remove(audio->dentry);
1389#endif
1390 kfree(audio);
1391 return 0;
1392}
1393
1394static void audpcm_post_event(struct audio *audio, int type,
1395 union msm_audio_event_payload payload)
1396{
1397 struct audpcm_event *e_node = NULL;
1398 unsigned long flags;
1399
1400 spin_lock_irqsave(&audio->event_queue_lock, flags);
1401
1402 if (!list_empty(&audio->free_event_queue)) {
1403 e_node = list_first_entry(&audio->free_event_queue,
1404 struct audpcm_event, list);
1405 list_del(&e_node->list);
1406 } else {
1407 e_node = kmalloc(sizeof(struct audpcm_event), GFP_ATOMIC);
1408 if (!e_node) {
1409 MM_ERR("No mem to post event %d\n", type);
1410 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
1411 return;
1412 }
1413 }
1414
1415 e_node->event_type = type;
1416 e_node->payload = payload;
1417
1418 list_add_tail(&e_node->list, &audio->event_queue);
1419 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
1420 wake_up(&audio->event_wait);
1421}
1422
1423#ifdef CONFIG_HAS_EARLYSUSPEND
1424static void audpcm_suspend(struct early_suspend *h)
1425{
1426 struct audpcm_suspend_ctl *ctl =
1427 container_of(h, struct audpcm_suspend_ctl, node);
1428 union msm_audio_event_payload payload;
1429
1430 MM_DBG("\n"); /* Macro prints the file name and function */
1431 audpcm_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload);
1432}
1433
1434static void audpcm_resume(struct early_suspend *h)
1435{
1436 struct audpcm_suspend_ctl *ctl =
1437 container_of(h, struct audpcm_suspend_ctl, node);
1438 union msm_audio_event_payload payload;
1439
1440 MM_DBG("\n"); /* Macro prints the file name and function */
1441 audpcm_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload);
1442}
1443#endif
1444
1445#ifdef CONFIG_DEBUG_FS
1446static ssize_t audpcm_debug_open(struct inode *inode, struct file *file)
1447{
1448 file->private_data = inode->i_private;
1449 return 0;
1450}
1451
1452static ssize_t audpcm_debug_read(struct file *file, char __user *buf,
1453 size_t count, loff_t *ppos)
1454{
1455 const int debug_bufmax = 4096;
1456 static char buffer[4096];
1457 int n = 0;
1458 struct audio *audio = file->private_data;
1459
1460 mutex_lock(&audio->lock);
1461 n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened);
1462 n += scnprintf(buffer + n, debug_bufmax - n,
1463 "enabled %d\n", audio->enabled);
1464 n += scnprintf(buffer + n, debug_bufmax - n,
1465 "stopped %d\n", audio->stopped);
1466 n += scnprintf(buffer + n, debug_bufmax - n,
1467 "out_buf_sz %d\n", audio->out[0].size);
1468 n += scnprintf(buffer + n, debug_bufmax - n,
1469 "volume %x \n", audio->volume);
1470 n += scnprintf(buffer + n, debug_bufmax - n,
1471 "sample rate %d \n", audio->out_sample_rate);
1472 n += scnprintf(buffer + n, debug_bufmax - n,
1473 "channel mode %d \n", audio->out_channel_mode);
1474 mutex_unlock(&audio->lock);
1475 /* Following variables are only useful for debugging when
1476 * when playback halts unexpectedly. Thus, no mutual exclusion
1477 * enforced
1478 */
1479 n += scnprintf(buffer + n, debug_bufmax - n,
1480 "wflush %d\n", audio->wflush);
1481 n += scnprintf(buffer + n, debug_bufmax - n,
1482 "running %d \n", audio->running);
1483 n += scnprintf(buffer + n, debug_bufmax - n,
1484 "dec state %d \n", audio->dec_state);
1485 n += scnprintf(buffer + n, debug_bufmax - n,
1486 "out_needed %d \n", audio->out_needed);
1487 n += scnprintf(buffer + n, debug_bufmax - n,
1488 "out_head %d \n", audio->out_head);
1489 n += scnprintf(buffer + n, debug_bufmax - n,
1490 "out_tail %d \n", audio->out_tail);
1491 n += scnprintf(buffer + n, debug_bufmax - n,
1492 "out[0].used %d \n", audio->out[0].used);
1493 n += scnprintf(buffer + n, debug_bufmax - n,
1494 "out[1].used %d \n", audio->out[1].used);
1495 buffer[n] = 0;
1496 return simple_read_from_buffer(buf, count, ppos, buffer, n);
1497}
1498
1499static const struct file_operations audpcm_debug_fops = {
1500 .read = audpcm_debug_read,
1501 .open = audpcm_debug_open,
1502};
1503#endif
1504
1505static int audio_open(struct inode *inode, struct file *file)
1506{
1507 struct audio *audio = NULL;
1508 int rc, i, dec_attrb, decid;
1509 struct audpcm_event *e_node = NULL;
1510 unsigned pmem_sz = DMASZ_MAX;
1511
1512#ifdef CONFIG_DEBUG_FS
1513 /* 4 bytes represents decoder number, 1 byte for terminate string */
1514 char name[sizeof "msm_pcm_dec_" + 5];
1515#endif
1516
1517 /* Allocate audio instance, set to zero */
1518 audio = kzalloc(sizeof(struct audio), GFP_KERNEL);
1519 if (!audio) {
1520 MM_ERR("no memory to allocate audio instance \n");
1521 rc = -ENOMEM;
1522 goto done;
1523 }
1524 MM_DBG("audio instance 0x%08x created\n", (int)audio);
1525
1526 /* Allocate the decoder */
1527 dec_attrb = AUDDEC_DEC_PCM;
1528 if (file->f_mode & FMODE_READ) {
1529 MM_ERR("Non-Tunneled mode not supported\n");
1530 rc = -EPERM;
1531 kfree(audio);
1532 goto done;
1533 } else
1534 dec_attrb |= MSM_AUD_MODE_TUNNEL;
1535
1536 decid = audpp_adec_alloc(dec_attrb, &audio->module_name,
1537 &audio->queue_id);
1538 if (decid < 0) {
1539 MM_ERR("No free decoder available\n");
1540 rc = -ENODEV;
1541 MM_DBG("audio instance 0x%08x freeing\n", (int)audio);
1542 kfree(audio);
1543 goto done;
1544 }
1545 audio->dec_id = decid & MSM_AUD_DECODER_MASK;
1546
1547 /* Non AIO interface */
1548 if (!(file->f_flags & O_NONBLOCK)) {
1549 while (pmem_sz >= DMASZ_MIN) {
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301550 MM_DBG("pmemsz = %d\n", pmem_sz);
1551 audio->phys = allocate_contiguous_ebi_nomap(pmem_sz,
1552 SZ_4K);
1553 if (audio->phys) {
1554 audio->map_v_write = msm_subsystem_map_buffer(
1555 audio->phys, pmem_sz,
1556 MSM_SUBSYSTEM_MAP_KADDR,
1557 NULL, 0);
1558 if (IS_ERR(audio->map_v_write)) {
1559 MM_ERR("could not map write\
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001560 buffers\n");
1561 rc = -ENOMEM;
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301562 free_contiguous_memory_by_paddr(
1563 audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001564 audpp_adec_free(audio->dec_id);
1565 MM_DBG("audio instance 0x%08x\
1566 freeing\n", (int)audio);
1567 kfree(audio);
1568 goto done;
1569 }
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301570 audio->data = audio->map_v_write->vaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001571 MM_DBG("write buf: phy addr 0x%08x kernel addr\
1572 0x%08x\n", audio->phys,\
1573 (int)audio->data);
1574 break;
1575 } else if (pmem_sz == DMASZ_MIN) {
1576 MM_ERR("could not allocate write buffers\n");
1577 rc = -ENOMEM;
1578 audpp_adec_free(audio->dec_id);
1579 MM_DBG("audio instance 0x%08x freeing\n",\
1580 (int)audio);
1581 kfree(audio);
1582 goto done;
1583 } else
1584 pmem_sz >>= 1;
1585 }
1586 audio->out_dma_sz = pmem_sz;
1587 }
1588
1589 rc = audmgr_open(&audio->audmgr);
1590 if (rc)
1591 goto err;
1592
1593 rc = msm_adsp_get(audio->module_name, &audio->audplay,
1594 &audpcmdec_adsp_ops, audio);
1595 if (rc) {
1596 MM_ERR("failed to get %s module\n", audio->module_name);
1597 audmgr_close(&audio->audmgr);
1598 goto err;
1599 }
1600
1601 rc = rmt_get_resource(audio);
1602 if (rc) {
1603 MM_ERR("ADSP resources are not available for PCM session \
1604 0x%08x on decoder: %d\n", (int)audio, audio->dec_id);
1605 audmgr_close(&audio->audmgr);
1606 msm_adsp_put(audio->audplay);
1607 goto err;
1608 }
1609
1610 if (file->f_flags & O_NONBLOCK) {
1611 MM_DBG("set to aio interface\n");
1612 audio->drv_status |= ADRV_STATUS_AIO_INTF;
1613 audio->drv_ops.send_data = audpcm_async_send_data;
1614 audio->drv_ops.out_flush = audpcm_async_flush;
1615 audio->drv_ops.fsync = audpcm_async_fsync;
1616 } else {
1617 MM_DBG("set to std io interface\n");
1618 audio->drv_ops.send_data = audplay_send_data;
1619 audio->drv_ops.out_flush = audio_flush;
1620 audio->drv_ops.fsync = audpcm_sync_fsync;
1621 audio->out[0].data = audio->data + 0;
1622 audio->out[0].addr = audio->phys + 0;
1623 audio->out[0].size = (audio->out_dma_sz >> 1);
1624
1625 audio->out[1].data = audio->data + audio->out[0].size;
1626 audio->out[1].addr = audio->phys + audio->out[0].size;
1627 audio->out[1].size = audio->out[0].size;
1628 }
1629
1630 /* Initialize all locks of audio instance */
1631 mutex_init(&audio->lock);
1632 mutex_init(&audio->write_lock);
1633 mutex_init(&audio->get_event_lock);
1634 spin_lock_init(&audio->dsp_lock);
1635 init_waitqueue_head(&audio->write_wait);
1636 INIT_LIST_HEAD(&audio->out_queue);
1637 INIT_LIST_HEAD(&audio->pmem_region_queue);
1638 INIT_LIST_HEAD(&audio->free_event_queue);
1639 INIT_LIST_HEAD(&audio->event_queue);
1640 init_waitqueue_head(&audio->wait);
1641 init_waitqueue_head(&audio->event_wait);
1642 spin_lock_init(&audio->event_queue_lock);
1643
1644 audio->out_sample_rate = 44100;
1645 audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
1646 audio->out_bits = AUDPP_CMD_WAV_PCM_WIDTH_16;
1647 audio->volume = 0x2000;
1648 audio->drv_ops.out_flush(audio);
1649
1650 file->private_data = audio;
1651 audio->opened = 1;
1652
1653#ifdef CONFIG_DEBUG_FS
1654 snprintf(name, sizeof name, "msm_pcm_dec_%04x", audio->dec_id);
1655 audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
1656 NULL, (void *) audio, &audpcm_debug_fops);
1657
1658 if (IS_ERR(audio->dentry))
1659 MM_DBG("debugfs_create_file failed\n");
1660#endif
1661#ifdef CONFIG_HAS_EARLYSUSPEND
1662 audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
1663 audio->suspend_ctl.node.resume = audpcm_resume;
1664 audio->suspend_ctl.node.suspend = audpcm_suspend;
1665 audio->suspend_ctl.audio = audio;
1666 register_early_suspend(&audio->suspend_ctl.node);
1667#endif
1668 for (i = 0; i < AUDPCM_EVENT_NUM; i++) {
1669 e_node = kmalloc(sizeof(struct audpcm_event), GFP_KERNEL);
1670 if (e_node)
1671 list_add_tail(&e_node->list, &audio->free_event_queue);
1672 else {
1673 MM_ERR("event pkt alloc failed\n");
1674 break;
1675 }
1676 }
1677done:
1678 return rc;
1679err:
1680 if (audio->data) {
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301681 msm_subsystem_unmap_buffer(audio->map_v_write);
1682 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001683 }
1684 audpp_adec_free(audio->dec_id);
1685 MM_DBG("audio instance 0x%08x freeing\n", (int)audio);
1686 kfree(audio);
1687 return rc;
1688}
1689
1690static const struct file_operations audio_pcm_fops = {
1691 .owner = THIS_MODULE,
1692 .open = audio_open,
1693 .release = audio_release,
1694 .write = audio_write,
1695 .unlocked_ioctl = audio_ioctl,
1696 .fsync = audpcm_fsync,
1697};
1698
1699struct miscdevice audio_pcm_misc = {
1700 .minor = MISC_DYNAMIC_MINOR,
1701 .name = "msm_pcm_dec",
1702 .fops = &audio_pcm_fops,
1703};
1704
1705static int __init audio_init(void)
1706{
1707 return misc_register(&audio_pcm_misc);
1708}
1709
1710device_initcall(audio_init);