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