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