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