blob: c639833a40c176e2cce30d3147a7c2434c8973e5 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* mp3 audio output device
2 *
3 * Copyright (C) 2008 Google, Inc.
4 * Copyright (C) 2008 HTC Corporation
Vinay Vaka051db722012-01-24 19:48:32 +05305 * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
Santosh Mardifdc227a2011-07-11 17:20:34 +053018#include <asm/atomic.h>
19#include <asm/ioctls.h>
20
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070021#include <linux/module.h>
22#include <linux/fs.h>
23#include <linux/miscdevice.h>
24#include <linux/uaccess.h>
25#include <linux/kthread.h>
26#include <linux/wait.h>
27#include <linux/dma-mapping.h>
28#include <linux/debugfs.h>
29#include <linux/delay.h>
30#include <linux/earlysuspend.h>
31#include <linux/list.h>
32#include <linux/android_pmem.h>
Santosh Mardifdc227a2011-07-11 17:20:34 +053033#include <linux/slab.h>
34#include <linux/memory_alloc.h>
35#include <linux/msm_audio.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070036#include <mach/msm_adsp.h>
37
Santosh Mardifdc227a2011-07-11 17:20:34 +053038#include <mach/iommu.h>
39#include <mach/iommu_domains.h>
40#include <mach/msm_subsystem_map.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070041#include <mach/qdsp5v2/audio_dev_ctl.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070042#include <mach/qdsp5v2/qdsp5audppmsg.h>
43#include <mach/qdsp5v2/qdsp5audplaycmdi.h>
44#include <mach/qdsp5v2/qdsp5audplaymsg.h>
45#include <mach/qdsp5v2/audio_dev_ctl.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>
49
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070050#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 AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF
62#define AUDDEC_DEC_MP3 2
63
64#define PCM_BUFSZ_MIN 4800 /* Hold one stereo MP3 frame */
65#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most
66 but support 2 buffers currently */
67#define ROUTING_MODE_FTRT 1
68#define ROUTING_MODE_RT 2
69/* Decoder status received from AUDPPTASK */
70#define AUDPP_DEC_STATUS_SLEEP 0
71#define AUDPP_DEC_STATUS_INIT 1
72#define AUDPP_DEC_STATUS_CFG 2
73#define AUDPP_DEC_STATUS_PLAY 3
74
75#define AUDMP3_METAFIELD_MASK 0xFFFF0000
76#define AUDMP3_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */
77#define AUDMP3_EOS_FLG_MASK 0x01
78#define AUDMP3_EOS_NONE 0x0 /* No EOS detected */
79#define AUDMP3_EOS_SET 0x1 /* EOS set in meta field */
80
81#define AUDMP3_EVENT_NUM 10 /* Default number of pre-allocated event packets */
82
83#define BITSTREAM_ERROR_THRESHOLD_VALUE 0x1 /* DEFAULT THRESHOLD VALUE */
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})
Vinay Vaka051db722012-01-24 19:48:32 +0530115struct audio;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700116
117struct buffer {
118 void *data;
119 unsigned size;
120 unsigned used; /* Input usage actual DSP produced PCM size */
121 unsigned addr;
122 unsigned short mfield_sz; /*only useful for data has meta field */
123};
124
125#ifdef CONFIG_HAS_EARLYSUSPEND
126struct audmp3_suspend_ctl {
127 struct early_suspend node;
128 struct audio *audio;
129};
130#endif
131
132struct audmp3_event {
133 struct list_head list;
134 int event_type;
135 union msm_audio_event_payload payload;
136};
137
138struct audmp3_pmem_region {
139 struct list_head list;
140 struct file *file;
141 int fd;
142 void *vaddr;
143 unsigned long paddr;
144 unsigned long kvaddr;
145 unsigned long len;
146 unsigned ref_cnt;
147};
148
149struct audmp3_buffer_node {
150 struct list_head list;
151 struct msm_audio_aio_buf buf;
152 unsigned long paddr;
153};
154
155struct audmp3_drv_operations {
156 void (*pcm_buf_update)(struct audio *, uint32_t *);
157 void (*buffer_refresh)(struct audio *);
158 void (*send_data)(struct audio *, unsigned);
159 void (*out_flush)(struct audio *);
160 void (*in_flush)(struct audio *);
161 int (*fsync)(struct audio *);
162};
163
164struct audio {
165 struct buffer out[2];
166
167 spinlock_t dsp_lock;
168
169 uint8_t out_head;
170 uint8_t out_tail;
171 uint8_t out_needed; /* number of buffers the dsp is waiting for */
172 unsigned out_dma_sz;
173 struct list_head out_queue; /* queue to retain output buffers */
174 atomic_t out_bytes;
175
176 struct mutex lock;
177 struct mutex write_lock;
178 wait_queue_head_t write_wait;
179
180 /* Host PCM section */
181 struct buffer in[PCM_BUF_MAX_COUNT];
182 struct mutex read_lock;
183 wait_queue_head_t read_wait; /* Wait queue for read */
184 char *read_data; /* pointer to reader buffer */
185 int32_t read_phys; /* physical address of reader buffer */
186 uint8_t read_next; /* index to input buffers to be read next */
187 uint8_t fill_next; /* index to buffer that DSP should be filling */
188 uint8_t pcm_buf_count; /* number of pcm buffer allocated */
189 struct list_head in_queue; /* queue to retain input buffers */
190 /* ---- End of Host PCM section */
191
192 struct msm_adsp_module *audplay;
193
194 /* configuration to use on next enable */
195 uint32_t out_sample_rate;
196 uint32_t out_channel_mode;
197
198 /* data allocated for various buffers */
199 char *data;
200 int32_t phys; /* physical address of write buffer */
Santosh Mardifdc227a2011-07-11 17:20:34 +0530201 struct msm_mapped_buffer *map_v_read;
202 struct msm_mapped_buffer *map_v_write;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700203
204 uint32_t drv_status;
205 int mfield; /* meta field embedded in data */
206 int rflush; /* Read flush */
207 int wflush; /* Write flush */
208 int opened;
209 int enabled;
210 int running;
211 int stopped; /* set when stopped, cleared on flush */
212 int pcm_feedback;
213 int buf_refresh;
214 int teos; /* valid only if tunnel mode & no data left for decoder */
215 enum msm_aud_decoder_state dec_state; /* Represents decoder state */
216 int reserved; /* A byte is being reserved */
217 char rsv_byte; /* Handle odd length user data */
218
219 const char *module_name;
220 unsigned queue_id;
221 uint16_t dec_id;
222 uint32_t read_ptr_offset;
223 int16_t source;
224
225#ifdef CONFIG_HAS_EARLYSUSPEND
226 struct audmp3_suspend_ctl suspend_ctl;
227#endif
228
229#ifdef CONFIG_DEBUG_FS
230 struct dentry *dentry;
231#endif
232
233 wait_queue_head_t wait;
234 struct list_head free_event_queue;
235 struct list_head event_queue;
236 wait_queue_head_t event_wait;
237 spinlock_t event_queue_lock;
238 struct mutex get_event_lock;
239 int event_abort;
240 /* AV sync Info */
241 int avsync_flag; /* Flag to indicate feedback from DSP */
242 wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */
243 /* flags, 48 bits sample/bytes counter per channel */
244 uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1];
245
246 uint32_t device_events;
247
248 struct list_head pmem_region_queue; /* protected by lock */
249 struct audmp3_drv_operations drv_ops;
250
251 struct msm_audio_bitstream_info stream_info;
252 struct msm_audio_bitstream_error_info bitstream_error_info;
253 uint32_t bitstream_error_threshold_value;
254
255 int eq_enable;
256 int eq_needs_commit;
257 struct audpp_cmd_cfg_object_params_eqalizer eq;
258 struct audpp_cmd_cfg_object_params_volume vol_pan;
259};
260
261static int auddec_dsp_config(struct audio *audio, int enable);
262static void audpp_cmd_cfg_adec_params(struct audio *audio);
263static void audpp_cmd_cfg_routing_mode(struct audio *audio);
264static void audplay_send_data(struct audio *audio, unsigned needed);
265static void audplay_error_threshold_config(struct audio *audio);
266static void audplay_config_hostpcm(struct audio *audio);
267static void audplay_buffer_refresh(struct audio *audio);
268static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
269static void audmp3_post_event(struct audio *audio, int type,
270 union msm_audio_event_payload payload);
271static unsigned long audmp3_pmem_fixup(struct audio *audio, void *addr,
272 unsigned long len, int ref_up);
273
274static void mp3_listner(u32 evt_id, union auddev_evt_data *evt_payload,
275 void *private_data)
276{
277 struct audio *audio = (struct audio *) private_data;
278 switch (evt_id) {
279 case AUDDEV_EVT_DEV_RDY:
280 MM_DBG(":AUDDEV_EVT_DEV_RDY\n");
281 audio->source |= (0x1 << evt_payload->routing_id);
282 if (audio->running == 1 && audio->enabled == 1)
283 audpp_route_stream(audio->dec_id, audio->source);
284
285 break;
286 case AUDDEV_EVT_DEV_RLS:
287 MM_DBG(":AUDDEV_EVT_DEV_RLS\n");
288 audio->source &= ~(0x1 << evt_payload->routing_id);
289 if (audio->running == 1 && audio->enabled == 1)
290 audpp_route_stream(audio->dec_id, audio->source);
291 break;
292 case AUDDEV_EVT_STREAM_VOL_CHG:
293 audio->vol_pan.volume = evt_payload->session_vol;
294 MM_DBG(":AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n",
295 audio->vol_pan.volume);
296 if (audio->running)
297 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan,
298 POPP);
299 break;
300 default:
301 MM_ERR(":ERROR:wrong event\n");
302 break;
303 }
304}
305/* must be called with audio->lock held */
306static int audio_enable(struct audio *audio)
307{
308 MM_DBG("\n"); /* Macro prints the file name and function */
309
310 if (audio->enabled)
311 return 0;
312
313 audio->dec_state = MSM_AUD_DECODER_STATE_NONE;
314 audio->out_tail = 0;
315 audio->out_needed = 0;
316
317 if (msm_adsp_enable(audio->audplay)) {
318 MM_ERR("msm_adsp_enable(audplay) failed\n");
319 return -ENODEV;
320 }
321
322 if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
323 MM_ERR("audpp_enable() failed\n");
324 msm_adsp_disable(audio->audplay);
325 return -ENODEV;
326 }
327
328 audio->enabled = 1;
329 return 0;
330}
331
332/* must be called with audio->lock held */
333static int audio_disable(struct audio *audio)
334{
335 int rc = 0;
336 MM_DBG("\n"); /* Macro prints the file name and function */
337 if (audio->enabled) {
338 audio->enabled = 0;
339 audio->dec_state = MSM_AUD_DECODER_STATE_NONE;
340 auddec_dsp_config(audio, 0);
341 rc = wait_event_interruptible_timeout(audio->wait,
342 audio->dec_state != MSM_AUD_DECODER_STATE_NONE,
343 msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS));
344 if (rc == 0)
345 rc = -ETIMEDOUT;
346 else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE)
347 rc = -EFAULT;
348 else
349 rc = 0;
350 wake_up(&audio->write_wait);
351 wake_up(&audio->read_wait);
352 msm_adsp_disable(audio->audplay);
353 audpp_disable(audio->dec_id, audio);
354 audio->out_needed = 0;
355 }
356 return rc;
357}
358
359/* ------------------- dsp --------------------- */
360static void audmp3_async_pcm_buf_update(struct audio *audio, uint32_t *payload)
361{
362 unsigned long flags;
363 union msm_audio_event_payload event_payload;
364 struct audmp3_buffer_node *filled_buf;
365 uint8_t index;
366
367 if (audio->rflush)
368 return;
369
370 spin_lock_irqsave(&audio->dsp_lock, flags);
371 for (index = 0; index < payload[1]; index++) {
372 BUG_ON(list_empty(&audio->in_queue));
373 filled_buf = list_first_entry(&audio->in_queue,
374 struct audmp3_buffer_node, list);
375 if (filled_buf->paddr == payload[2 + index * 2]) {
376 list_del(&filled_buf->list);
377 event_payload.aio_buf = filled_buf->buf;
378 event_payload.aio_buf.data_len =
379 payload[3 + index * 2];
380 MM_DBG("pcm buf %p data_len %d\n", filled_buf,
381 event_payload.aio_buf.data_len);
382 audmp3_post_event(audio, AUDIO_EVENT_READ_DONE,
383 event_payload);
384 kfree(filled_buf);
385 } else {
386 MM_ERR("expected=%lx ret=%x\n", filled_buf->paddr,
387 payload[2 + index * 2]);
388 break;
389 }
390 }
391
392 audio->drv_status &= ~ADRV_STATUS_IBUF_GIVEN;
393 audio->drv_ops.buffer_refresh(audio);
394 spin_unlock_irqrestore(&audio->dsp_lock, flags);
395
396}
397
398static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload)
399{
400 uint8_t index;
401 unsigned long flags;
402
403 if (audio->rflush)
404 return;
405
406 spin_lock_irqsave(&audio->dsp_lock, flags);
407 for (index = 0; index < payload[1]; index++) {
408 if (audio->in[audio->fill_next].addr ==
409 payload[2 + index * 2]) {
410 MM_DBG("in[%d] ready\n", audio->fill_next);
411 audio->in[audio->fill_next].used =
412 payload[3 + index * 2];
413 if ((++audio->fill_next) == audio->pcm_buf_count)
414 audio->fill_next = 0;
415
416 } else {
417 MM_ERR("expected=%x ret=%x\n",
418 audio->in[audio->fill_next].addr,
419 payload[2 + index * 2]);
420 break;
421 }
422 }
423 if (audio->in[audio->fill_next].used == 0) {
424 audio->drv_ops.buffer_refresh(audio);
425 } else {
426 MM_DBG("read cannot keep up\n");
427 audio->buf_refresh = 1;
428 }
429 wake_up(&audio->read_wait);
430 spin_unlock_irqrestore(&audio->dsp_lock, flags);
431
432}
433
434static void audmp3_bitstream_error_info(struct audio *audio, uint32_t *payload)
435{
436 unsigned long flags;
437 union msm_audio_event_payload e_payload;
438
439 if (payload[0] != AUDDEC_DEC_MP3) {
440 MM_ERR("Unexpected bitstream error info from DSP:\
441 Invalid decoder\n");
442 return;
443 }
444
445 /* get stream info from DSP msg */
446 spin_lock_irqsave(&audio->dsp_lock, flags);
447
448 audio->bitstream_error_info.dec_id = payload[0];
449 audio->bitstream_error_info.err_msg_indicator = payload[1];
450 audio->bitstream_error_info.err_type = payload[2];
451
452 spin_unlock_irqrestore(&audio->dsp_lock, flags);
453 MM_ERR("bit_stream_error_type=%d error_count=%d\n",
454 audio->bitstream_error_info.err_type, (0x0000FFFF &
455 audio->bitstream_error_info.err_msg_indicator));
456
457 /* send event to ARM to notify error info coming */
458 e_payload.error_info = audio->bitstream_error_info;
459 audmp3_post_event(audio, AUDIO_EVENT_BITSTREAM_ERROR_INFO, e_payload);
460}
461
462static void audmp3_update_stream_info(struct audio *audio, uint32_t *payload)
463{
464 unsigned long flags;
465 union msm_audio_event_payload e_payload;
466
467 /* get stream info from DSP msg */
468 spin_lock_irqsave(&audio->dsp_lock, flags);
469
470 audio->stream_info.codec_type = AUDIO_CODEC_TYPE_MP3;
471 audio->stream_info.chan_info = (0x0000FFFF & payload[1]);
472 audio->stream_info.sample_rate = (0x0000FFFF & payload[2]);
473 audio->stream_info.bit_stream_info = (0x0000FFFF & payload[3]);
474 audio->stream_info.bit_rate = payload[4];
475
476 spin_unlock_irqrestore(&audio->dsp_lock, flags);
477 MM_DBG("chan_info=%d, sample_rate=%d, bit_stream_info=%d\n",
478 audio->stream_info.chan_info,
479 audio->stream_info.sample_rate,
480 audio->stream_info.bit_stream_info);
481
482 /* send event to ARM to notify steam info coming */
483 e_payload.stream_info = audio->stream_info;
484 audmp3_post_event(audio, AUDIO_EVENT_STREAM_INFO, e_payload);
485}
486
487static void audplay_dsp_event(void *data, unsigned id, size_t len,
488 void (*getevent) (void *ptr, size_t len))
489{
490 struct audio *audio = data;
491 uint32_t msg[28];
492 getevent(msg, sizeof(msg));
493
494 MM_DBG("msg_id=%x\n", id);
495
496 switch (id) {
497 case AUDPLAY_MSG_DEC_NEEDS_DATA:
498 audio->drv_ops.send_data(audio, 1);
499 break;
500
501 case AUDPLAY_MSG_BUFFER_UPDATE:
502 audio->drv_ops.pcm_buf_update(audio, msg);
503 break;
504
505 case AUDPLAY_UP_STREAM_INFO:
506 if ((msg[1] & AUDPLAY_STREAM_INFO_MSG_MASK) ==
507 AUDPLAY_STREAM_INFO_MSG_MASK) {
508 audmp3_bitstream_error_info(audio, msg);
509 } else {
510 audmp3_update_stream_info(audio, msg);
511 }
512 break;
513
514 case AUDPLAY_UP_OUTPORT_FLUSH_ACK:
515 MM_DBG("OUTPORT_FLUSH_ACK\n");
516 audio->rflush = 0;
517 wake_up(&audio->read_wait);
518 if (audio->pcm_feedback)
519 audio->drv_ops.buffer_refresh(audio);
520 break;
521
522 case ADSP_MESSAGE_ID:
523 MM_DBG("Received ADSP event: module enable(audplaytask)\n");
524 break;
525
526 default:
527 MM_ERR("unexpected message from decoder \n");
528 break;
529 }
530}
531
532static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
533{
534 struct audio *audio = private;
535
536 switch (id) {
537 case AUDPP_MSG_STATUS_MSG:{
538 unsigned status = msg[1];
539
540 switch (status) {
541 case AUDPP_DEC_STATUS_SLEEP: {
542 uint16_t reason = msg[2];
543 MM_DBG("decoder status: sleep reason=0x%04x\n",
544 reason);
545 if ((reason == AUDPP_MSG_REASON_MEM)
546 || (reason ==
547 AUDPP_MSG_REASON_NODECODER)) {
548 audio->dec_state =
549 MSM_AUD_DECODER_STATE_FAILURE;
550 wake_up(&audio->wait);
551 } else if (reason == AUDPP_MSG_REASON_NONE) {
552 /* decoder is in disable state */
553 audio->dec_state =
554 MSM_AUD_DECODER_STATE_CLOSE;
555 wake_up(&audio->wait);
556 }
557 break;
558 }
559 case AUDPP_DEC_STATUS_INIT:
560 MM_DBG("decoder status: init \n");
561 if (audio->pcm_feedback)
562 audpp_cmd_cfg_routing_mode(audio);
563 else
564 audpp_cmd_cfg_adec_params(audio);
565 break;
566
567 case AUDPP_DEC_STATUS_CFG:
568 MM_DBG("decoder status: cfg \n");
569 break;
570 case AUDPP_DEC_STATUS_PLAY:
571 MM_DBG("decoder status: play \n");
572 /* send mixer command */
573 audpp_route_stream(audio->dec_id,
574 audio->source);
575 if (audio->pcm_feedback) {
576 audplay_error_threshold_config(audio);
577 audplay_config_hostpcm(audio);
578 audio->drv_ops.buffer_refresh(audio);
579 }
580 audio->dec_state =
581 MSM_AUD_DECODER_STATE_SUCCESS;
582 wake_up(&audio->wait);
583 break;
584 default:
585 MM_ERR("unknown decoder status \n");
586 break;
587 }
588 break;
589 }
590 case AUDPP_MSG_CFG_MSG:
591 if (msg[0] == AUDPP_MSG_ENA_ENA) {
592 MM_DBG("CFG_MSG ENABLE\n");
593 auddec_dsp_config(audio, 1);
594 audio->out_needed = 0;
595 audio->running = 1;
596 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan,
597 POPP);
598 audpp_dsp_set_eq(audio->dec_id, audio->eq_enable,
599 &audio->eq, POPP);
600 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
601 MM_DBG("CFG_MSG DISABLE\n");
602 audio->running = 0;
603 } else {
604 MM_DBG("CFG_MSG %d?\n", msg[0]);
605 }
606 break;
607 case AUDPP_MSG_ROUTING_ACK:
608 MM_DBG("ROUTING_ACK mode=%d\n", msg[1]);
609 audpp_cmd_cfg_adec_params(audio);
610 break;
611
612 case AUDPP_MSG_FLUSH_ACK:
613 MM_DBG("FLUSH_ACK\n");
614 audio->wflush = 0;
615 audio->rflush = 0;
616 wake_up(&audio->write_wait);
617 if (audio->pcm_feedback)
618 audio->drv_ops.buffer_refresh(audio);
619 break;
620
621 case AUDPP_MSG_PCMDMAMISSED:
622 MM_DBG("PCMDMAMISSED\n");
623 audio->teos = 1;
624 wake_up(&audio->write_wait);
625 break;
626
627 case AUDPP_MSG_AVSYNC_MSG:
628 MM_DBG("AUDPP_MSG_AVSYNC_MSG\n");
629 memcpy(&audio->avsync[0], msg, sizeof(audio->avsync));
630 audio->avsync_flag = 1;
631 wake_up(&audio->avsync_wait);
632 break;
633
634 default:
635 MM_ERR("UNKNOWN (%d)\n", id);
636 }
637
638}
639
640
641struct msm_adsp_ops audplay_adsp_ops = {
642 .event = audplay_dsp_event,
643};
644
645
646#define audplay_send_queue0(audio, cmd, len) \
647 msm_adsp_write(audio->audplay, audio->queue_id, \
648 cmd, len)
649
650static int auddec_dsp_config(struct audio *audio, int enable)
651{
652 struct audpp_cmd_cfg_dec_type cfg_dec_cmd;
653
654 memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd));
655
656 cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
657 if (enable)
658 cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
659 AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_MP3;
660 else
661 cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
662 AUDPP_CMD_DIS_DEC_V;
663 cfg_dec_cmd.dm_mode = 0x0;
664 cfg_dec_cmd.stream_id = audio->dec_id;
665 return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd));
666}
667
668static void audpp_cmd_cfg_adec_params(struct audio *audio)
669{
670 struct audpp_cmd_cfg_adec_params_mp3 cmd;
671
672 memset(&cmd, 0, sizeof(cmd));
673 cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
674 cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_MP3_LEN;
675 cmd.common.dec_id = audio->dec_id;
676 cmd.common.input_sampling_frequency = audio->out_sample_rate;
677
678 audpp_send_queue2(&cmd, sizeof(cmd));
679}
680
681static void audpp_cmd_cfg_routing_mode(struct audio *audio)
682{
683 struct audpp_cmd_routing_mode cmd;
684 MM_DBG("\n"); /* Macro prints the file name and function */
685 memset(&cmd, 0, sizeof(cmd));
686 cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
687 cmd.object_number = audio->dec_id;
688 if (audio->pcm_feedback)
689 cmd.routing_mode = ROUTING_MODE_FTRT;
690 else
691 cmd.routing_mode = ROUTING_MODE_RT;
692
693 audpp_send_queue1(&cmd, sizeof(cmd));
694}
695
696static int audplay_dsp_send_data_avail(struct audio *audio,
697 unsigned idx, unsigned len)
698{
699 struct audplay_cmd_bitstream_data_avail_nt2 cmd;
700
701 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2;
702 if (audio->mfield)
703 cmd.decoder_id = AUDMP3_METAFIELD_MASK |
704 (audio->out[idx].mfield_sz >> 1);
705 else
706 cmd.decoder_id = audio->dec_id;
707 cmd.buf_ptr = audio->out[idx].addr;
708 cmd.buf_size = len/2;
709 cmd.partition_number = 0;
710 return audplay_send_queue0(audio, &cmd, sizeof(cmd));
711}
712/* Caller holds irq_lock */
713static void audmp3_async_buffer_refresh(struct audio *audio)
714{
715 struct audplay_cmd_buffer_refresh refresh_cmd;
716 struct audmp3_buffer_node *next_buf;
717
718 if (!audio->running ||
719 audio->drv_status & ADRV_STATUS_IBUF_GIVEN)
720 return;
721
722 if (!list_empty(&audio->in_queue)) {
723 next_buf = list_first_entry(&audio->in_queue,
724 struct audmp3_buffer_node, list);
725 if (!next_buf)
726 return;
727 MM_DBG("next buf %p phy %lx len %d\n", next_buf,
728 next_buf->paddr, next_buf->buf.buf_len);
729 refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
730 refresh_cmd.num_buffers = 1;
731 refresh_cmd.buf0_address = next_buf->paddr;
732 refresh_cmd.buf0_length = next_buf->buf.buf_len -
733 (next_buf->buf.buf_len % 576) +
734 (audio->mfield ? 24 : 0); /* Mp3 frame size */
735 refresh_cmd.buf_read_count = 0;
736 audio->drv_status |= ADRV_STATUS_IBUF_GIVEN;
737 (void) audplay_send_queue0(audio, &refresh_cmd,
738 sizeof(refresh_cmd));
739 }
740
741}
742
743static void audplay_buffer_refresh(struct audio *audio)
744{
745 struct audplay_cmd_buffer_refresh refresh_cmd;
746
747 refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
748 refresh_cmd.num_buffers = 1;
749 refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
750 refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
751 (audio->in[audio->fill_next].size % 576) +
752 (audio->mfield ? 24 : 0); /* Mp3 frame size */
753 refresh_cmd.buf_read_count = 0;
754 MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address,
755 refresh_cmd.buf0_length);
756 (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
757}
758
759static void audplay_error_threshold_config(struct audio *audio)
760{
761 union audplay_cmd_channel_info ch_cfg_cmd;
762
763 MM_DBG("\n"); /* Macro prints the file name and function */
764 ch_cfg_cmd.thr_update.cmd_id = AUDPLAY_CMD_CHANNEL_INFO;
765 ch_cfg_cmd.thr_update.threshold_update = AUDPLAY_ERROR_THRESHOLD_ENABLE;
766 ch_cfg_cmd.thr_update.threshold_value =
767 audio->bitstream_error_threshold_value;
768 (void)audplay_send_queue0(audio, &ch_cfg_cmd, sizeof(ch_cfg_cmd));
769}
770
771static void audplay_config_hostpcm(struct audio *audio)
772{
773 struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
774
775 MM_DBG("\n"); /* Macro prints the file name and function */
776 cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
777 cfg_cmd.max_buffers = 1;
778 cfg_cmd.byte_swap = 0;
779 cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
780 cfg_cmd.feedback_frequency = 1;
781 cfg_cmd.partition_number = 0;
782 (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
783
784}
785
786static void audplay_outport_flush(struct audio *audio)
787{
788 struct audplay_cmd_outport_flush op_flush_cmd;
789
790 MM_DBG("\n"); /* Macro prints the file name and function */
791 op_flush_cmd.cmd_id = AUDPLAY_CMD_OUTPORT_FLUSH;
792 (void)audplay_send_queue0(audio, &op_flush_cmd, sizeof(op_flush_cmd));
793}
794
795static void audmp3_async_send_data(struct audio *audio, unsigned needed)
796{
797 unsigned long flags;
798
799 spin_lock_irqsave(&audio->dsp_lock, flags);
800 if (!audio->running)
801 goto done;
802
803 if (needed && !audio->wflush) {
804 audio->out_needed = 1;
805 if (audio->drv_status & ADRV_STATUS_OBUF_GIVEN) {
806 /* pop one node out of queue */
807 union msm_audio_event_payload payload;
808 struct audmp3_buffer_node *used_buf;
809
810 MM_DBG("consumed\n");
811 BUG_ON(list_empty(&audio->out_queue));
812 used_buf = list_first_entry(&audio->out_queue,
813 struct audmp3_buffer_node, list);
814 list_del(&used_buf->list);
815 payload.aio_buf = used_buf->buf;
816 audmp3_post_event(audio, AUDIO_EVENT_WRITE_DONE,
817 payload);
818 kfree(used_buf);
819 audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN;
820 }
821
822 }
823
824 if (audio->out_needed) {
825 struct audmp3_buffer_node *next_buf;
826 struct audplay_cmd_bitstream_data_avail_nt2 cmd;
827 if (!list_empty(&audio->out_queue)) {
828 next_buf = list_first_entry(&audio->out_queue,
829 struct audmp3_buffer_node, list);
830 MM_DBG("next_buf %p\n", next_buf);
831 if (next_buf) {
832 MM_DBG("next buf phy %lx len %d\n",
833 next_buf->paddr,
834 next_buf->buf.data_len);
835
836 cmd.cmd_id =
837 AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2;
838 if (audio->mfield)
839 cmd.decoder_id = AUDMP3_METAFIELD_MASK |
840 (next_buf->buf.mfield_sz >> 1);
841 else
842 cmd.decoder_id = audio->dec_id;
843 cmd.buf_ptr = (unsigned) next_buf->paddr;
844 cmd.buf_size = next_buf->buf.data_len >> 1;
845 cmd.partition_number = 0;
846 audplay_send_queue0(audio, &cmd, sizeof(cmd));
847 audio->out_needed = 0;
848 audio->drv_status |= ADRV_STATUS_OBUF_GIVEN;
849 }
850 }
851 }
852
853done:
854 spin_unlock_irqrestore(&audio->dsp_lock, flags);
855}
856
857static void audplay_send_data(struct audio *audio, unsigned needed)
858{
859 struct buffer *frame;
860 unsigned long flags;
861
862 spin_lock_irqsave(&audio->dsp_lock, flags);
863 if (!audio->running)
864 goto done;
865
866 if (needed && !audio->wflush) {
867 /* We were called from the callback because the DSP
868 * requested more data. Note that the DSP does want
869 * more data, and if a buffer was in-flight, mark it
870 * as available (since the DSP must now be done with
871 * it).
872 */
873 audio->out_needed = 1;
874 frame = audio->out + audio->out_tail;
875 if (frame->used == 0xffffffff) {
876 MM_DBG("frame %d free\n", audio->out_tail);
877 frame->used = 0;
878 audio->out_tail ^= 1;
879 wake_up(&audio->write_wait);
880 }
881 }
882
883 if (audio->out_needed) {
884 /* If the DSP currently wants data and we have a
885 * buffer available, we will send it and reset
886 * the needed flag. We'll mark the buffer as in-flight
887 * so that it won't be recycled until the next buffer
888 * is requested
889 */
890
891 frame = audio->out + audio->out_tail;
892 if (frame->used) {
893 BUG_ON(frame->used == 0xffffffff);
894 MM_DBG("frame %d busy\n", audio->out_tail);
895 audplay_dsp_send_data_avail(audio, audio->out_tail,
896 frame->used);
897 frame->used = 0xffffffff;
898 audio->out_needed = 0;
899 }
900 }
901done:
902 spin_unlock_irqrestore(&audio->dsp_lock, flags);
903}
904
905/* ------------------- device --------------------- */
906static void audmp3_async_flush(struct audio *audio)
907{
908 struct audmp3_buffer_node *buf_node;
909 struct list_head *ptr, *next;
910 union msm_audio_event_payload payload;
911
912 MM_DBG("\n"); /* Macro prints the file name and function */
913 list_for_each_safe(ptr, next, &audio->out_queue) {
914 buf_node = list_entry(ptr, struct audmp3_buffer_node, list);
915 list_del(&buf_node->list);
916 payload.aio_buf = buf_node->buf;
917 audmp3_post_event(audio, AUDIO_EVENT_WRITE_DONE,
918 payload);
919 kfree(buf_node);
920 }
921 audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN;
922 audio->out_needed = 0;
923 atomic_set(&audio->out_bytes, 0);
924}
925
926static void audio_flush(struct audio *audio)
927{
928 audio->out[0].used = 0;
929 audio->out[1].used = 0;
930 audio->out_head = 0;
931 audio->out_tail = 0;
932 audio->reserved = 0;
933 audio->out_needed = 0;
934 atomic_set(&audio->out_bytes, 0);
935}
936
937static void audmp3_async_flush_pcm_buf(struct audio *audio)
938{
939 struct audmp3_buffer_node *buf_node;
940 struct list_head *ptr, *next;
941 union msm_audio_event_payload payload;
942
943 MM_DBG("\n"); /* Macro prints the file name and function */
944 list_for_each_safe(ptr, next, &audio->in_queue) {
945 buf_node = list_entry(ptr, struct audmp3_buffer_node, list);
946 list_del(&buf_node->list);
947 payload.aio_buf = buf_node->buf;
948 payload.aio_buf.data_len = 0;
949 audmp3_post_event(audio, AUDIO_EVENT_READ_DONE,
950 payload);
951 kfree(buf_node);
952 }
953 audio->drv_status &= ~ADRV_STATUS_IBUF_GIVEN;
954
955}
956
957static void audio_flush_pcm_buf(struct audio *audio)
958{
959 uint8_t index;
960
961 for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
962 audio->in[index].used = 0;
963
964 audio->buf_refresh = 0;
965 audio->read_next = 0;
966 audio->fill_next = 0;
967}
968
969static void audio_ioport_reset(struct audio *audio)
970{
971 if (audio->drv_status & ADRV_STATUS_AIO_INTF) {
972 /* If fsync is in progress, make sure
973 * return value of fsync indicates
974 * abort due to flush
975 */
976 if (audio->drv_status & ADRV_STATUS_FSYNC) {
977 MM_DBG("fsync in progress\n");
978 wake_up(&audio->write_wait);
979 mutex_lock(&audio->write_lock);
980 audio->drv_ops.out_flush(audio);
981 mutex_unlock(&audio->write_lock);
982 } else
983 audio->drv_ops.out_flush(audio);
984 audio->drv_ops.in_flush(audio);
985 } else {
986 /* Make sure read/write thread are free from
987 * sleep and knowing that system is not able
988 * to process io request at the moment
989 */
990 wake_up(&audio->write_wait);
991 mutex_lock(&audio->write_lock);
992 audio->drv_ops.out_flush(audio);
993 mutex_unlock(&audio->write_lock);
994 wake_up(&audio->read_wait);
995 mutex_lock(&audio->read_lock);
996 audio->drv_ops.in_flush(audio);
997 mutex_unlock(&audio->read_lock);
998 }
999 audio->avsync_flag = 1;
1000 wake_up(&audio->avsync_wait);
1001}
1002
1003static int audmp3_events_pending(struct audio *audio)
1004{
1005 unsigned long flags;
1006 int empty;
1007
1008 spin_lock_irqsave(&audio->event_queue_lock, flags);
1009 empty = !list_empty(&audio->event_queue);
1010 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
1011 return empty || audio->event_abort;
1012}
1013
1014static void audmp3_reset_event_queue(struct audio *audio)
1015{
1016 unsigned long flags;
1017 struct audmp3_event *drv_evt;
1018 struct list_head *ptr, *next;
1019
1020 spin_lock_irqsave(&audio->event_queue_lock, flags);
1021 list_for_each_safe(ptr, next, &audio->event_queue) {
1022 drv_evt = list_first_entry(&audio->event_queue,
1023 struct audmp3_event, list);
1024 list_del(&drv_evt->list);
1025 kfree(drv_evt);
1026 }
1027 list_for_each_safe(ptr, next, &audio->free_event_queue) {
1028 drv_evt = list_first_entry(&audio->free_event_queue,
1029 struct audmp3_event, list);
1030 list_del(&drv_evt->list);
1031 kfree(drv_evt);
1032 }
1033 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
1034
1035 return;
1036}
1037
1038static long audmp3_process_event_req(struct audio *audio, void __user *arg)
1039{
1040 long rc;
1041 struct msm_audio_event usr_evt;
1042 struct audmp3_event *drv_evt = NULL;
1043 int timeout;
1044 unsigned long flags;
1045
1046 if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event)))
1047 return -EFAULT;
1048
1049 timeout = (int) usr_evt.timeout_ms;
1050
1051 if (timeout > 0) {
1052 rc = wait_event_interruptible_timeout(
1053 audio->event_wait, audmp3_events_pending(audio),
1054 msecs_to_jiffies(timeout));
1055 if (rc == 0)
1056 return -ETIMEDOUT;
1057 } else {
1058 rc = wait_event_interruptible(
1059 audio->event_wait, audmp3_events_pending(audio));
1060 }
1061
1062 if (rc < 0)
1063 return rc;
1064
1065 if (audio->event_abort) {
1066 audio->event_abort = 0;
1067 return -ENODEV;
1068 }
1069
1070 rc = 0;
1071
1072 spin_lock_irqsave(&audio->event_queue_lock, flags);
1073 if (!list_empty(&audio->event_queue)) {
1074 drv_evt = list_first_entry(&audio->event_queue,
1075 struct audmp3_event, list);
1076 list_del(&drv_evt->list);
1077 }
1078 if (drv_evt) {
1079 usr_evt.event_type = drv_evt->event_type;
1080 usr_evt.event_payload = drv_evt->payload;
1081 list_add_tail(&drv_evt->list, &audio->free_event_queue);
1082 } else
1083 rc = -1;
1084 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
1085
1086 if (drv_evt->event_type == AUDIO_EVENT_WRITE_DONE ||
1087 drv_evt->event_type == AUDIO_EVENT_READ_DONE) {
1088 mutex_lock(&audio->lock);
1089 audmp3_pmem_fixup(audio, drv_evt->payload.aio_buf.buf_addr,
1090 drv_evt->payload.aio_buf.buf_len, 0);
1091 mutex_unlock(&audio->lock);
1092 }
1093 if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt)))
1094 rc = -EFAULT;
1095
1096 return rc;
1097}
1098
1099static int audmp3_pmem_check(struct audio *audio,
1100 void *vaddr, unsigned long len)
1101{
1102 struct audmp3_pmem_region *region_elt;
1103 struct audmp3_pmem_region t = { .vaddr = vaddr, .len = len };
1104
1105 list_for_each_entry(region_elt, &audio->pmem_region_queue, list) {
1106 if (CONTAINS(region_elt, &t) || CONTAINS(&t, region_elt) ||
1107 OVERLAPS(region_elt, &t)) {
1108 MM_ERR("region (vaddr %p len %ld)"
1109 " clashes with registered region"
1110 " (vaddr %p paddr %p len %ld)\n",
1111 vaddr, len,
1112 region_elt->vaddr,
1113 (void *)region_elt->paddr,
1114 region_elt->len);
1115 return -EINVAL;
1116 }
1117 }
1118
1119 return 0;
1120}
1121
1122static int audmp3_pmem_add(struct audio *audio,
1123 struct msm_audio_pmem_info *info)
1124{
1125 unsigned long paddr, kvaddr, len;
1126 struct file *file;
1127 struct audmp3_pmem_region *region;
1128 int rc = -EINVAL;
1129
1130 MM_DBG("\n"); /* Macro prints the file name and function */
1131 region = kmalloc(sizeof(*region), GFP_KERNEL);
1132
1133 if (!region) {
1134 rc = -ENOMEM;
1135 goto end;
1136 }
1137
1138 if (get_pmem_file(info->fd, &paddr, &kvaddr, &len, &file)) {
1139 kfree(region);
1140 goto end;
1141 }
1142
1143 rc = audmp3_pmem_check(audio, info->vaddr, len);
1144 if (rc < 0) {
1145 put_pmem_file(file);
1146 kfree(region);
1147 goto end;
1148 }
1149
1150 region->vaddr = info->vaddr;
1151 region->fd = info->fd;
1152 region->paddr = paddr;
1153 region->kvaddr = kvaddr;
1154 region->len = len;
1155 region->file = file;
1156 region->ref_cnt = 0;
1157 MM_DBG("add region paddr %lx vaddr %p, len %lu\n", region->paddr,
1158 region->vaddr, region->len);
1159 list_add_tail(&region->list, &audio->pmem_region_queue);
1160end:
1161 return rc;
1162}
1163
1164static int audmp3_pmem_remove(struct audio *audio,
1165 struct msm_audio_pmem_info *info)
1166{
1167 struct audmp3_pmem_region *region;
1168 struct list_head *ptr, *next;
1169 int rc = -EINVAL;
1170
1171 MM_DBG("info fd %d vaddr %p\n", info->fd, info->vaddr);
1172
1173 list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
1174 region = list_entry(ptr, struct audmp3_pmem_region, list);
1175
1176 if ((region->fd == info->fd) &&
1177 (region->vaddr == info->vaddr)) {
1178 if (region->ref_cnt) {
1179 MM_DBG("region %p in use ref_cnt %d\n",
1180 region, region->ref_cnt);
1181 break;
1182 }
1183 MM_DBG("remove region fd %d vaddr %p \n",
1184 info->fd, info->vaddr);
1185 list_del(&region->list);
1186 put_pmem_file(region->file);
1187 kfree(region);
1188 rc = 0;
1189 break;
1190 }
1191 }
1192
1193 return rc;
1194}
1195
1196static int audmp3_pmem_lookup_vaddr(struct audio *audio, void *addr,
1197 unsigned long len, struct audmp3_pmem_region **region)
1198{
1199 struct audmp3_pmem_region *region_elt;
1200
1201 int match_count = 0;
1202
1203 *region = NULL;
1204
1205 /* returns physical address or zero */
1206 list_for_each_entry(region_elt, &audio->pmem_region_queue,
1207 list) {
1208 if (addr >= region_elt->vaddr &&
1209 addr < region_elt->vaddr + region_elt->len &&
1210 addr + len <= region_elt->vaddr + region_elt->len) {
1211 /* offset since we could pass vaddr inside a registerd
1212 * pmem buffer
1213 */
1214
1215 match_count++;
1216 if (!*region)
1217 *region = region_elt;
1218 }
1219 }
1220
1221 if (match_count > 1) {
1222 MM_ERR("multiple hits for vaddr %p, len %ld\n", addr, len);
1223 list_for_each_entry(region_elt,
1224 &audio->pmem_region_queue, list) {
1225 if (addr >= region_elt->vaddr &&
1226 addr < region_elt->vaddr + region_elt->len &&
1227 addr + len <= region_elt->vaddr + region_elt->len)
1228 MM_ERR("\t%p, %ld --> %p\n", region_elt->vaddr,
1229 region_elt->len,
1230 (void *)region_elt->paddr);
1231 }
1232 }
1233
1234 return *region ? 0 : -1;
1235}
1236
1237unsigned long audmp3_pmem_fixup(struct audio *audio, void *addr,
1238 unsigned long len, int ref_up)
1239{
1240 struct audmp3_pmem_region *region;
1241 unsigned long paddr;
1242 int ret;
1243
1244 ret = audmp3_pmem_lookup_vaddr(audio, addr, len, &region);
1245 if (ret) {
1246 MM_ERR("lookup (%p, %ld) failed\n", addr, len);
1247 return 0;
1248 }
1249 if (ref_up)
1250 region->ref_cnt++;
1251 else
1252 region->ref_cnt--;
1253 MM_DBG("found region %p ref_cnt %d\n", region, region->ref_cnt);
1254 paddr = region->paddr + (addr - region->vaddr);
1255 return paddr;
1256}
1257
1258/* audio -> lock must be held at this point */
1259static int audmp3_aio_buf_add(struct audio *audio, unsigned dir,
1260 void __user *arg)
1261{
1262 unsigned long flags;
1263 struct audmp3_buffer_node *buf_node;
1264
1265 buf_node = kmalloc(sizeof(*buf_node), GFP_KERNEL);
1266
1267 if (!buf_node)
1268 return -ENOMEM;
1269
1270 if (copy_from_user(&buf_node->buf, arg, sizeof(buf_node->buf))) {
1271 kfree(buf_node);
1272 return -EFAULT;
1273 }
1274
1275 MM_DBG("node %p dir %x buf_addr %p buf_len %d data_len \
1276 %d\n", buf_node, dir,
1277 buf_node->buf.buf_addr, buf_node->buf.buf_len,
1278 buf_node->buf.data_len);
1279
1280 buf_node->paddr = audmp3_pmem_fixup(
1281 audio, buf_node->buf.buf_addr,
1282 buf_node->buf.buf_len, 1);
1283
1284 if (dir) {
1285 /* write */
1286 if (!buf_node->paddr ||
1287 (buf_node->paddr & 0x1) ||
1288 (buf_node->buf.data_len & 0x1) ||
1289 (!audio->pcm_feedback &&
1290 !buf_node->buf.data_len)) {
1291 kfree(buf_node);
1292 return -EINVAL;
1293 }
1294 spin_lock_irqsave(&audio->dsp_lock, flags);
1295 list_add_tail(&buf_node->list, &audio->out_queue);
1296 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1297 audio->drv_ops.send_data(audio, 0);
1298 } else {
1299 /* read */
1300 if (!buf_node->paddr ||
1301 (buf_node->paddr & 0x1) ||
1302 (buf_node->buf.buf_len < PCM_BUFSZ_MIN)) {
1303 kfree(buf_node);
1304 return -EINVAL;
1305 }
1306 spin_lock_irqsave(&audio->dsp_lock, flags);
1307 list_add_tail(&buf_node->list, &audio->in_queue);
1308 audio->drv_ops.buffer_refresh(audio);
1309 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1310 }
1311
1312 MM_DBG("Add buf_node %p paddr %lx\n", buf_node, buf_node->paddr);
1313
1314 return 0;
1315}
1316
1317static int audio_enable_eq(struct audio *audio, int enable)
1318{
1319 if (audio->eq_enable == enable && !audio->eq_needs_commit)
1320 return 0;
1321
1322 audio->eq_enable = enable;
1323
1324 if (audio->running) {
1325 audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP);
1326 audio->eq_needs_commit = 0;
1327 }
1328 return 0;
1329}
1330
1331static int audio_get_avsync_data(struct audio *audio,
1332 struct msm_audio_stats *stats)
1333{
1334 int rc = -EINVAL;
1335 unsigned long flags;
1336
1337 local_irq_save(flags);
1338 if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) {
1339 /* av_sync sample count */
1340 stats->sample_count = (audio->avsync[2] << 16) |
1341 (audio->avsync[3]);
1342
1343 /* av_sync byte_count */
1344 stats->byte_count = (audio->avsync[5] << 16) |
1345 (audio->avsync[6]);
1346
1347 audio->avsync_flag = 0;
1348 rc = 0;
1349 }
1350 local_irq_restore(flags);
1351 return rc;
1352
1353}
1354
1355static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1356{
1357 struct audio *audio = file->private_data;
1358 int rc = -EINVAL;
1359 unsigned long flags = 0;
1360 uint16_t enable_mask;
1361 int enable;
1362 int prev_state;
1363
1364 MM_DBG("cmd = %d\n", cmd);
1365
1366 if (cmd == AUDIO_GET_STATS) {
1367 struct msm_audio_stats stats;
1368
1369 audio->avsync_flag = 0;
1370 memset(&stats, 0, sizeof(stats));
1371 if (audpp_query_avsync(audio->dec_id) < 0)
1372 return rc;
1373
1374 rc = wait_event_interruptible_timeout(audio->avsync_wait,
1375 (audio->avsync_flag == 1),
1376 msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT));
1377
1378 if (rc < 0)
1379 return rc;
1380 else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) {
1381 if (audio_get_avsync_data(audio, &stats) < 0)
1382 return rc;
1383
1384 if (copy_to_user((void *)arg, &stats, sizeof(stats)))
1385 return -EFAULT;
1386 return 0;
1387 } else
1388 return -EAGAIN;
1389 }
1390
1391 switch (cmd) {
1392 case AUDIO_ENABLE_AUDPP:
1393 if (copy_from_user(&enable_mask, (void *) arg,
1394 sizeof(enable_mask))) {
1395 rc = -EFAULT;
1396 break;
1397 }
1398
1399 spin_lock_irqsave(&audio->dsp_lock, flags);
1400 enable = (enable_mask & EQ_ENABLE) ? 1 : 0;
1401 audio_enable_eq(audio, enable);
1402 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1403 rc = 0;
1404 break;
1405 case AUDIO_SET_VOLUME:
1406 spin_lock_irqsave(&audio->dsp_lock, flags);
1407 audio->vol_pan.volume = arg;
1408 if (audio->running)
1409 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan,
1410 POPP);
1411 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1412 rc = 0;
1413 break;
1414
1415 case AUDIO_SET_PAN:
1416 spin_lock_irqsave(&audio->dsp_lock, flags);
1417 audio->vol_pan.pan = arg;
1418 if (audio->running)
1419 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan,
1420 POPP);
1421 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1422 rc = 0;
1423 break;
1424
1425 case AUDIO_SET_EQ:
1426 prev_state = audio->eq_enable;
1427 audio->eq_enable = 0;
1428 if (copy_from_user(&audio->eq.num_bands, (void *) arg,
1429 sizeof(audio->eq) -
1430 (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) {
1431 rc = -EFAULT;
1432 break;
1433 }
1434 audio->eq_enable = prev_state;
1435 audio->eq_needs_commit = 1;
1436 rc = 0;
1437 break;
1438 }
1439
1440 if (-EINVAL != rc)
1441 return rc;
1442
1443 if (cmd == AUDIO_GET_EVENT) {
1444 MM_DBG(" AUDIO_GET_EVENT\n");
1445 if (mutex_trylock(&audio->get_event_lock)) {
1446 rc = audmp3_process_event_req(audio,
1447 (void __user *) arg);
1448 mutex_unlock(&audio->get_event_lock);
1449 } else
1450 rc = -EBUSY;
1451 return rc;
1452 }
1453
1454 if (cmd == AUDIO_ABORT_GET_EVENT) {
1455 audio->event_abort = 1;
1456 wake_up(&audio->event_wait);
1457 return 0;
1458 }
1459
1460 mutex_lock(&audio->lock);
1461 switch (cmd) {
1462 case AUDIO_START:
1463 MM_DBG("AUDIO_START\n");
1464 rc = audio_enable(audio);
1465 if (!rc) {
1466 rc = wait_event_interruptible_timeout(audio->wait,
1467 audio->dec_state != MSM_AUD_DECODER_STATE_NONE,
1468 msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS));
1469 MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc);
1470
1471 if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS)
1472 rc = -ENODEV;
1473 else
1474 rc = 0;
1475 }
1476 break;
1477 case AUDIO_STOP:
1478 MM_DBG("AUDIO_STOP\n");
1479 rc = audio_disable(audio);
1480 audio->stopped = 1;
1481 audio_ioport_reset(audio);
1482 audio->stopped = 0;
1483 break;
1484 case AUDIO_FLUSH:
1485 MM_DBG("AUDIO_FLUSH\n");
1486 audio->rflush = 1;
1487 audio->wflush = 1;
1488 audio_ioport_reset(audio);
1489 if (audio->running) {
1490 audpp_flush(audio->dec_id);
1491 rc = wait_event_interruptible(audio->write_wait,
1492 !audio->wflush);
1493 if (rc < 0) {
1494 MM_ERR("AUDIO_FLUSH interrupted\n");
1495 rc = -EINTR;
1496 }
1497 } else {
1498 audio->rflush = 0;
1499 audio->wflush = 0;
1500 }
1501 break;
1502 case AUDIO_OUTPORT_FLUSH:
1503 MM_DBG("AUDIO_OUTPORT_FLUSH\n");
1504 audio->rflush = 1;
1505 if (audio->drv_status & ADRV_STATUS_AIO_INTF) {
1506 audio->drv_ops.in_flush(audio);
1507 } else {
1508 wake_up(&audio->read_wait);
1509 mutex_lock(&audio->read_lock);
1510 audio->drv_ops.in_flush(audio);
1511 mutex_unlock(&audio->read_lock);
1512 }
1513 audplay_outport_flush(audio);
1514 rc = wait_event_interruptible(audio->read_wait,
1515 !audio->rflush);
1516 if (rc < 0) {
1517 MM_ERR("AUDPLAY_OUTPORT_FLUSH interrupted\n");
1518 rc = -EINTR;
1519 }
1520 break;
1521 case AUDIO_SET_CONFIG: {
1522 struct msm_audio_config config;
1523 if (copy_from_user(&config, (void *) arg, sizeof(config))) {
1524 rc = -EFAULT;
1525 break;
1526 }
1527 if (config.channel_count == 1) {
1528 config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
1529 } else if (config.channel_count == 2) {
1530 config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V;
1531 } else {
1532 rc = -EINVAL;
1533 break;
1534 }
1535 audio->mfield = config.meta_field;
1536 audio->out_sample_rate = config.sample_rate;
1537 audio->out_channel_mode = config.channel_count;
1538 rc = 0;
1539 break;
1540 }
1541 case AUDIO_GET_CONFIG: {
1542 struct msm_audio_config config;
1543 config.buffer_size = (audio->out_dma_sz >> 1);
1544 config.buffer_count = 2;
1545 config.sample_rate = audio->out_sample_rate;
1546 if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V)
1547 config.channel_count = 1;
1548 else
1549 config.channel_count = 2;
1550 config.meta_field = 0;
1551 config.unused[0] = 0;
1552 config.unused[1] = 0;
1553 config.unused[2] = 0;
1554 if (copy_to_user((void *) arg, &config, sizeof(config)))
1555 rc = -EFAULT;
1556 else
1557 rc = 0;
1558 break;
1559 }
1560 case AUDIO_GET_PCM_CONFIG:{
1561 struct msm_audio_pcm_config config;
1562 config.pcm_feedback = audio->pcm_feedback;
1563 config.buffer_count = PCM_BUF_MAX_COUNT;
1564 config.buffer_size = PCM_BUFSZ_MIN;
1565 if (copy_to_user((void *)arg, &config,
1566 sizeof(config)))
1567 rc = -EFAULT;
1568 else
1569 rc = 0;
1570 break;
1571 }
1572 case AUDIO_SET_PCM_CONFIG:{
1573 struct msm_audio_pcm_config config;
1574 if (copy_from_user
1575 (&config, (void *)arg, sizeof(config))) {
1576 rc = -EFAULT;
1577 break;
1578 }
1579
1580 if (config.pcm_feedback != audio->pcm_feedback) {
1581 MM_ERR("Not sufficient permission to"
1582 "change the playback mode\n");
1583 rc = -EACCES;
1584 break;
1585 }
1586 if (audio->drv_status & ADRV_STATUS_AIO_INTF) {
1587 rc = 0;
1588 break;
1589 }
1590
1591 if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
1592 (config.buffer_count == 1))
1593 config.buffer_count = PCM_BUF_MAX_COUNT;
1594
1595 if (config.buffer_size < PCM_BUFSZ_MIN)
1596 config.buffer_size = PCM_BUFSZ_MIN;
1597
1598 /* Check if pcm feedback is required */
1599 if ((config.pcm_feedback) && (!audio->read_data)) {
1600 MM_DBG("allocate PCM buffer %d\n",
1601 config.buffer_count *
1602 config.buffer_size);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301603 audio->read_phys =
1604 allocate_contiguous_ebi_nomap(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001605 config.buffer_size *
1606 config.buffer_count,
Santosh Mardifdc227a2011-07-11 17:20:34 +05301607 SZ_4K);
1608 if (!audio->read_phys) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001609 rc = -ENOMEM;
1610 break;
1611 }
Santosh Mardifdc227a2011-07-11 17:20:34 +05301612 audio->map_v_read = msm_subsystem_map_buffer(
1613 audio->read_phys,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001614 config.buffer_size *
Santosh Mardifdc227a2011-07-11 17:20:34 +05301615 config.buffer_count,
1616 MSM_SUBSYSTEM_MAP_KADDR
1617 , NULL, 0);
1618 if (IS_ERR(audio->map_v_read)) {
1619 MM_ERR("failed to map read buffer"
1620 " physical address\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001621 rc = -ENOMEM;
Santosh Mardifdc227a2011-07-11 17:20:34 +05301622 free_contiguous_memory_by_paddr(
1623 audio->read_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001624 } else {
1625 uint8_t index;
1626 uint32_t offset = 0;
Santosh Mardifdc227a2011-07-11 17:20:34 +05301627 audio->read_data =
1628 audio->map_v_read->vaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001629 audio->buf_refresh = 0;
1630 audio->pcm_buf_count =
1631 config.buffer_count;
1632 audio->read_next = 0;
1633 audio->fill_next = 0;
1634
1635 for (index = 0;
1636 index < config.buffer_count;
1637 index++) {
1638 audio->in[index].data =
1639 audio->read_data + offset;
1640 audio->in[index].addr =
1641 audio->read_phys + offset;
1642 audio->in[index].size =
1643 config.buffer_size;
1644 audio->in[index].used = 0;
1645 offset += config.buffer_size;
1646 }
1647 rc = 0;
1648 MM_DBG("read buf: phy addr \
1649 0x%08x kernel addr 0x%08x\n",
1650 audio->read_phys,
1651 (int)audio->read_data);
1652 }
1653 } else {
1654 rc = 0;
1655 }
1656 break;
1657 }
1658 case AUDIO_PAUSE:
1659 MM_DBG("AUDIO_PAUSE %ld\n", arg);
1660 rc = audpp_pause(audio->dec_id, (int) arg);
1661 break;
1662
1663 case AUDIO_GET_STREAM_INFO:{
1664 if (audio->stream_info.sample_rate == 0) {
1665 /* haven't received DSP stream event,
1666 the stream info is not updated */
1667 rc = -EPERM;
1668 break;
1669 }
1670 if (copy_to_user((void *)arg, &audio->stream_info,
1671 sizeof(struct msm_audio_bitstream_info)))
1672 rc = -EFAULT;
1673 else
1674 rc = 0;
1675 break;
1676 }
1677 case AUDIO_GET_BITSTREAM_ERROR_INFO:{
1678 if ((audio->bitstream_error_info.err_msg_indicator &
1679 AUDPLAY_STREAM_INFO_MSG_MASK) ==
1680 AUDPLAY_STREAM_INFO_MSG_MASK) {
1681 /* haven't received bitstream error info event,
1682 the bitstream error info is not updated */
1683 rc = -EPERM;
1684 break;
1685 }
1686 if (copy_to_user((void *)arg, &audio->bitstream_error_info,
1687 sizeof(struct msm_audio_bitstream_error_info)))
1688 rc = -EFAULT;
1689 else
1690 rc = 0;
1691 break;
1692 }
1693
1694 case AUDIO_REGISTER_PMEM: {
1695 struct msm_audio_pmem_info info;
1696 MM_DBG("AUDIO_REGISTER_PMEM\n");
1697 if (copy_from_user(&info, (void *) arg, sizeof(info)))
1698 rc = -EFAULT;
1699 else
1700 rc = audmp3_pmem_add(audio, &info);
1701 break;
1702 }
1703
1704 case AUDIO_DEREGISTER_PMEM: {
1705 struct msm_audio_pmem_info info;
1706 MM_DBG("AUDIO_DEREGISTER_PMEM\n");
1707 if (copy_from_user(&info, (void *) arg, sizeof(info)))
1708 rc = -EFAULT;
1709 else
1710 rc = audmp3_pmem_remove(audio, &info);
1711 break;
1712 }
1713 case AUDIO_ASYNC_WRITE:
1714 if (audio->drv_status & ADRV_STATUS_FSYNC)
1715 rc = -EBUSY;
1716 else
1717 rc = audmp3_aio_buf_add(audio, 1, (void __user *) arg);
1718 break;
1719
1720 case AUDIO_ASYNC_READ:
1721 if (audio->pcm_feedback)
1722 rc = audmp3_aio_buf_add(audio, 0, (void __user *) arg);
1723 else
1724 rc = -EPERM;
1725 break;
1726 case AUDIO_GET_SESSION_ID:
1727 if (copy_to_user((void *) arg, &audio->dec_id,
1728 sizeof(unsigned short)))
1729 rc = -EFAULT;
1730 else
1731 rc = 0;
1732 break;
1733 case AUDIO_SET_ERR_THRESHOLD_VALUE:
1734 if (copy_from_user(&audio->bitstream_error_threshold_value,
1735 (void *)arg, sizeof(uint32_t)))
1736 rc = -EFAULT;
1737 else
1738 rc = 0;
1739 break;
1740 default:
1741 rc = -EINVAL;
1742 }
1743 mutex_unlock(&audio->lock);
1744 return rc;
1745}
1746
1747/* Only useful in tunnel-mode */
1748int audmp3_async_fsync(struct audio *audio)
1749{
1750 int rc = 0;
1751
1752 MM_DBG("\n"); /* Macro prints the file name and function */
1753
1754 /* Blocking client sends more data */
1755 mutex_lock(&audio->lock);
1756 audio->drv_status |= ADRV_STATUS_FSYNC;
1757 mutex_unlock(&audio->lock);
1758
1759 mutex_lock(&audio->write_lock);
1760 /* pcm dmamiss message is sent continously
1761 * when decoder is starved so no race
1762 * condition concern
1763 */
1764 audio->teos = 0;
1765
1766 rc = wait_event_interruptible(audio->write_wait,
1767 (audio->teos && audio->out_needed &&
1768 list_empty(&audio->out_queue))
1769 || audio->wflush || audio->stopped);
1770
1771 if (audio->stopped || audio->wflush)
1772 rc = -EBUSY;
1773
1774 mutex_unlock(&audio->write_lock);
1775 mutex_lock(&audio->lock);
1776 audio->drv_status &= ~ADRV_STATUS_FSYNC;
1777 mutex_unlock(&audio->lock);
1778
1779 return rc;
1780}
1781
1782int audmp3_sync_fsync(struct audio *audio)
1783{
1784 struct buffer *frame;
1785 int rc = 0;
1786
1787 MM_DBG("\n"); /* Macro prints the file name and function */
1788
1789 mutex_lock(&audio->write_lock);
1790
1791 rc = wait_event_interruptible(audio->write_wait,
1792 (!audio->out[0].used &&
1793 !audio->out[1].used &&
1794 audio->out_needed) || audio->wflush);
1795
1796 if (rc < 0)
1797 goto done;
1798 else if (audio->wflush) {
1799 rc = -EBUSY;
1800 goto done;
1801 }
1802
1803 if (audio->reserved) {
1804 MM_DBG("send reserved byte\n");
1805 frame = audio->out + audio->out_tail;
1806 ((char *) frame->data)[0] = audio->rsv_byte;
1807 ((char *) frame->data)[1] = 0;
1808 frame->used = 2;
1809 audio->drv_ops.send_data(audio, 0);
1810
1811 rc = wait_event_interruptible(audio->write_wait,
1812 (!audio->out[0].used &&
1813 !audio->out[1].used &&
1814 audio->out_needed) || audio->wflush);
1815
1816 if (rc < 0)
1817 goto done;
1818 else if (audio->wflush) {
1819 rc = -EBUSY;
1820 goto done;
1821 }
1822 }
1823
1824 /* pcm dmamiss message is sent continously
1825 * when decoder is starved so no race
1826 * condition concern
1827 */
1828 audio->teos = 0;
1829
1830 rc = wait_event_interruptible(audio->write_wait,
1831 audio->teos || audio->wflush);
1832
1833 if (audio->wflush)
1834 rc = -EBUSY;
1835
1836done:
1837 mutex_unlock(&audio->write_lock);
1838 return rc;
1839}
1840
1841int audmp3_fsync(struct file *file, int datasync)
1842{
1843 struct audio *audio = file->private_data;
1844
1845 if (!audio->running || audio->pcm_feedback)
1846 return -EINVAL;
1847
1848 return audio->drv_ops.fsync(audio);
1849}
1850
1851static ssize_t audio_read(struct file *file, char __user *buf, size_t count,
1852 loff_t *pos)
1853{
1854 struct audio *audio = file->private_data;
1855 const char __user *start = buf;
1856 int rc = 0;
1857
1858 if (audio->drv_status & ADRV_STATUS_AIO_INTF)
1859 return -EPERM;
1860 else if (!audio->pcm_feedback)
1861 return 0; /* PCM feedback disabled. Nothing to read */
1862
1863 mutex_lock(&audio->read_lock);
1864 MM_DBG("%d \n", count);
1865 while (count > 0) {
1866 rc = wait_event_interruptible_timeout(
1867 audio->read_wait,
1868 (audio->in[audio->read_next].
1869 used > 0) || (audio->stopped)
1870 || (audio->rflush),
1871 msecs_to_jiffies(MSM_AUD_BUFFER_UPDATE_WAIT_MS));
1872
1873 if (rc == 0) {
1874 rc = -ETIMEDOUT;
1875 break;
1876 } else if (rc < 0)
1877 break;
1878
1879 if (audio->stopped || audio->rflush) {
1880 rc = -EBUSY;
1881 break;
1882 }
1883
1884 if (count < audio->in[audio->read_next].used) {
1885 /* Read must happen in frame boundary. Since
1886 * driver does not know frame size, read count
1887 * must be greater or equal
1888 * to size of PCM samples
1889 */
1890 MM_DBG("no partial frame done reading\n");
1891 break;
1892 } else {
1893 MM_DBG("read from in[%d]\n", audio->read_next);
1894
1895 if (copy_to_user
1896 (buf, audio->in[audio->read_next].data,
1897 audio->in[audio->read_next].used)) {
1898 MM_ERR("invalid addr %x \n", (unsigned int)buf);
1899 rc = -EFAULT;
1900 break;
1901 }
1902 count -= audio->in[audio->read_next].used;
1903 buf += audio->in[audio->read_next].used;
1904 audio->in[audio->read_next].used = 0;
1905 if ((++audio->read_next) == audio->pcm_buf_count)
1906 audio->read_next = 0;
1907 break; /* Force to exit while loop
1908 * to prevent output thread
1909 * sleep too long if data is
1910 * not ready at this moment.
1911 */
1912 }
1913 }
1914
1915 /* don't feed output buffer to HW decoder during flushing
1916 * buffer refresh command will be sent once flush completes
1917 * send buf refresh command here can confuse HW decoder
1918 */
1919 if (audio->buf_refresh && !audio->rflush) {
1920 audio->buf_refresh = 0;
1921 MM_DBG("kick start pcm feedback again\n");
1922 audio->drv_ops.buffer_refresh(audio);
1923 }
1924
1925 mutex_unlock(&audio->read_lock);
1926
1927 if (buf > start)
1928 rc = buf - start;
1929
1930 MM_DBG("read %d bytes\n", rc);
1931 return rc;
1932}
1933
1934static int audmp3_process_eos(struct audio *audio,
1935 const char __user *buf_start, unsigned short mfield_size)
1936{
1937 int rc = 0;
1938 struct buffer *frame;
1939 char *buf_ptr;
1940
1941 if (audio->reserved) {
1942 MM_DBG("flush reserve byte\n");
1943 frame = audio->out + audio->out_head;
1944 buf_ptr = frame->data;
1945 rc = wait_event_interruptible(audio->write_wait,
1946 (frame->used == 0)
1947 || (audio->stopped)
1948 || (audio->wflush));
1949 if (rc < 0)
1950 goto done;
1951 if (audio->stopped || audio->wflush) {
1952 rc = -EBUSY;
1953 goto done;
1954 }
1955
1956 buf_ptr[0] = audio->rsv_byte;
1957 buf_ptr[1] = 0;
1958 audio->out_head ^= 1;
1959 frame->mfield_sz = 0;
1960 frame->used = 2;
1961 audio->reserved = 0;
1962 audio->drv_ops.send_data(audio, 0);
1963 }
1964
1965 frame = audio->out + audio->out_head;
1966
1967 rc = wait_event_interruptible(audio->write_wait,
1968 (audio->out_needed &&
1969 audio->out[0].used == 0 &&
1970 audio->out[1].used == 0)
1971 || (audio->stopped)
1972 || (audio->wflush));
1973
1974 if (rc < 0)
1975 goto done;
1976 if (audio->stopped || audio->wflush) {
1977 rc = -EBUSY;
1978 goto done;
1979 }
1980
1981 if (copy_from_user(frame->data, buf_start, mfield_size)) {
1982 rc = -EFAULT;
1983 goto done;
1984 }
1985
1986 frame->mfield_sz = mfield_size;
1987 audio->out_head ^= 1;
1988 frame->used = mfield_size;
1989 audio->drv_ops.send_data(audio, 0);
1990done:
1991 return rc;
1992}
1993
1994static ssize_t audio_write(struct file *file, const char __user *buf,
1995 size_t count, loff_t *pos)
1996{
1997 struct audio *audio = file->private_data;
1998 const char __user *start = buf;
1999 struct buffer *frame;
2000 size_t xfer;
2001 char *cpy_ptr;
2002 int rc = 0, eos_condition = AUDMP3_EOS_NONE;
2003 unsigned dsize;
2004 unsigned short mfield_size = 0;
2005
2006 if (audio->drv_status & ADRV_STATUS_AIO_INTF)
2007 return -EPERM;
2008
2009 MM_DBG("cnt=%d\n", count);
2010
2011 mutex_lock(&audio->write_lock);
2012 while (count > 0) {
2013 frame = audio->out + audio->out_head;
2014 cpy_ptr = frame->data;
2015 dsize = 0;
2016 rc = wait_event_interruptible(audio->write_wait,
2017 (frame->used == 0)
2018 || (audio->stopped)
2019 || (audio->wflush));
2020 if (rc < 0)
2021 break;
2022 if (audio->stopped || audio->wflush) {
2023 rc = -EBUSY;
2024 break;
2025 }
2026 if (audio->mfield) {
2027 if (buf == start) {
2028 /* Processing beginning of user buffer */
2029 if (__get_user(mfield_size,
2030 (unsigned short __user *) buf)) {
2031 rc = -EFAULT;
2032 break;
2033 } else if (mfield_size > count) {
2034 rc = -EINVAL;
2035 break;
2036 }
2037 MM_DBG("mf offset_val %x\n", mfield_size);
2038 if (copy_from_user(cpy_ptr, buf, mfield_size)) {
2039 rc = -EFAULT;
2040 break;
2041 }
2042 /* Check if EOS flag is set and buffer has
2043 * contains just meta field
2044 */
2045 if (cpy_ptr[AUDMP3_EOS_FLG_OFFSET] &
2046 AUDMP3_EOS_FLG_MASK) {
2047 MM_DBG("EOS SET\n");
2048 eos_condition = AUDMP3_EOS_SET;
2049 if (mfield_size == count) {
2050 buf += mfield_size;
2051 break;
2052 } else
2053 cpy_ptr[AUDMP3_EOS_FLG_OFFSET]
2054 &= ~AUDMP3_EOS_FLG_MASK;
2055 }
2056 cpy_ptr += mfield_size;
2057 count -= mfield_size;
2058 dsize += mfield_size;
2059 buf += mfield_size;
2060 } else {
2061 mfield_size = 0;
2062 MM_DBG("continuous buffer\n");
2063 }
2064 frame->mfield_sz = mfield_size;
2065 }
2066
2067 if (audio->reserved) {
2068 MM_DBG("append reserved byte %x\n", audio->rsv_byte);
2069 *cpy_ptr = audio->rsv_byte;
2070 xfer = (count > ((frame->size - mfield_size) - 1)) ?
2071 (frame->size - mfield_size) - 1 : count;
2072 cpy_ptr++;
2073 dsize += 1;
2074 audio->reserved = 0;
2075 } else
2076 xfer = (count > (frame->size - mfield_size)) ?
2077 (frame->size - mfield_size) : count;
2078
2079 if (copy_from_user(cpy_ptr, buf, xfer)) {
2080 rc = -EFAULT;
2081 break;
2082 }
2083
2084 dsize += xfer;
2085 if (dsize & 1) {
2086 audio->rsv_byte = ((char *) frame->data)[dsize - 1];
2087 MM_DBG("odd length buf reserve last byte %x\n",
2088 audio->rsv_byte);
2089 audio->reserved = 1;
2090 dsize--;
2091 }
2092 count -= xfer;
2093 buf += xfer;
2094
2095 if (dsize > 0) {
2096 audio->out_head ^= 1;
2097 frame->used = dsize;
2098 audio->drv_ops.send_data(audio, 0);
2099 }
2100 }
2101 if (eos_condition == AUDMP3_EOS_SET)
2102 rc = audmp3_process_eos(audio, start, mfield_size);
2103 mutex_unlock(&audio->write_lock);
2104 if (!rc) {
2105 if (buf > start)
2106 return buf - start;
2107 }
2108 return rc;
2109}
2110
2111static void audmp3_reset_pmem_region(struct audio *audio)
2112{
2113 struct audmp3_pmem_region *region;
2114 struct list_head *ptr, *next;
2115
2116 list_for_each_safe(ptr, next, &audio->pmem_region_queue) {
2117 region = list_entry(ptr, struct audmp3_pmem_region, list);
2118 list_del(&region->list);
2119 put_pmem_file(region->file);
2120 kfree(region);
2121 }
2122
2123 return;
2124}
2125
2126static int audio_release(struct inode *inode, struct file *file)
2127{
2128 struct audio *audio = file->private_data;
2129
2130 MM_INFO("audio instance 0x%08x freeing\n", (int)audio);
2131 mutex_lock(&audio->lock);
2132 auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id);
2133 audio_disable(audio);
2134 audio->drv_ops.out_flush(audio);
2135 audio->drv_ops.in_flush(audio);
2136 audmp3_reset_pmem_region(audio);
2137
2138 msm_adsp_put(audio->audplay);
2139 audpp_adec_free(audio->dec_id);
2140#ifdef CONFIG_HAS_EARLYSUSPEND
2141 unregister_early_suspend(&audio->suspend_ctl.node);
2142#endif
2143 audio->opened = 0;
2144 audio->event_abort = 1;
2145 wake_up(&audio->event_wait);
2146 audmp3_reset_event_queue(audio);
2147 if (audio->data) {
Santosh Mardifdc227a2011-07-11 17:20:34 +05302148 msm_subsystem_unmap_buffer(audio->map_v_write);
2149 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002150 }
2151 if (audio->read_data) {
Santosh Mardifdc227a2011-07-11 17:20:34 +05302152 msm_subsystem_unmap_buffer(audio->map_v_read);
2153 free_contiguous_memory_by_paddr(audio->read_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002154 }
2155 mutex_unlock(&audio->lock);
2156#ifdef CONFIG_DEBUG_FS
2157 if (audio->dentry)
2158 debugfs_remove(audio->dentry);
2159#endif
2160 kfree(audio);
2161 return 0;
2162}
2163
2164static void audmp3_post_event(struct audio *audio, int type,
2165 union msm_audio_event_payload payload)
2166{
2167 struct audmp3_event *e_node = NULL;
2168 unsigned long flags;
2169
2170 spin_lock_irqsave(&audio->event_queue_lock, flags);
2171
2172 if (!list_empty(&audio->free_event_queue)) {
2173 e_node = list_first_entry(&audio->free_event_queue,
2174 struct audmp3_event, list);
2175 list_del(&e_node->list);
2176 } else {
2177 e_node = kmalloc(sizeof(struct audmp3_event), GFP_ATOMIC);
2178 if (!e_node) {
2179 MM_ERR("No mem to post event %d\n", type);
2180 return;
2181 }
2182 }
2183
2184 e_node->event_type = type;
2185 e_node->payload = payload;
2186
2187 list_add_tail(&e_node->list, &audio->event_queue);
2188 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
2189 wake_up(&audio->event_wait);
2190}
2191
2192#ifdef CONFIG_HAS_EARLYSUSPEND
2193static void audmp3_suspend(struct early_suspend *h)
2194{
2195 struct audmp3_suspend_ctl *ctl =
2196 container_of(h, struct audmp3_suspend_ctl, node);
2197 union msm_audio_event_payload payload;
2198
2199 MM_DBG("\n"); /* Macro prints the file name and function */
2200 audmp3_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload);
2201}
2202
2203static void audmp3_resume(struct early_suspend *h)
2204{
2205 struct audmp3_suspend_ctl *ctl =
2206 container_of(h, struct audmp3_suspend_ctl, node);
2207 union msm_audio_event_payload payload;
2208
2209 MM_DBG("\n"); /* Macro prints the file name and function */
2210 audmp3_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload);
2211}
2212#endif
2213
2214#ifdef CONFIG_DEBUG_FS
2215static ssize_t audmp3_debug_open(struct inode *inode, struct file *file)
2216{
2217 file->private_data = inode->i_private;
2218 return 0;
2219}
2220
2221static ssize_t audmp3_debug_read(struct file *file, char __user *buf,
2222 size_t count, loff_t *ppos)
2223{
2224 const int debug_bufmax = 4096;
2225 static char buffer[4096];
2226 int n = 0, i;
2227 struct audio *audio = file->private_data;
2228
2229 mutex_lock(&audio->lock);
2230 n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened);
2231 n += scnprintf(buffer + n, debug_bufmax - n,
2232 "enabled %d\n", audio->enabled);
2233 n += scnprintf(buffer + n, debug_bufmax - n,
2234 "stopped %d\n", audio->stopped);
2235 n += scnprintf(buffer + n, debug_bufmax - n,
2236 "pcm_feedback %d\n", audio->pcm_feedback);
2237 n += scnprintf(buffer + n, debug_bufmax - n,
2238 "out_buf_sz %d\n", audio->out[0].size);
2239 n += scnprintf(buffer + n, debug_bufmax - n,
2240 "pcm_buf_count %d \n", audio->pcm_buf_count);
2241 n += scnprintf(buffer + n, debug_bufmax - n,
2242 "pcm_buf_sz %d \n", audio->in[0].size);
2243 n += scnprintf(buffer + n, debug_bufmax - n,
2244 "volume %x \n", audio->vol_pan.volume);
2245 n += scnprintf(buffer + n, debug_bufmax - n,
2246 "sample rate %d \n", audio->out_sample_rate);
2247 n += scnprintf(buffer + n, debug_bufmax - n,
2248 "channel mode %d \n", audio->out_channel_mode);
2249 mutex_unlock(&audio->lock);
2250 /* Following variables are only useful for debugging when
2251 * when playback halts unexpectedly. Thus, no mutual exclusion
2252 * enforced
2253 */
2254 n += scnprintf(buffer + n, debug_bufmax - n,
2255 "wflush %d\n", audio->wflush);
2256 n += scnprintf(buffer + n, debug_bufmax - n,
2257 "rflush %d\n", audio->rflush);
2258 n += scnprintf(buffer + n, debug_bufmax - n,
2259 "running %d \n", audio->running);
2260 n += scnprintf(buffer + n, debug_bufmax - n,
2261 "dec state %d \n", audio->dec_state);
2262 n += scnprintf(buffer + n, debug_bufmax - n,
2263 "out_needed %d \n", audio->out_needed);
2264 n += scnprintf(buffer + n, debug_bufmax - n,
2265 "out_head %d \n", audio->out_head);
2266 n += scnprintf(buffer + n, debug_bufmax - n,
2267 "out_tail %d \n", audio->out_tail);
2268 n += scnprintf(buffer + n, debug_bufmax - n,
2269 "out[0].used %d \n", audio->out[0].used);
2270 n += scnprintf(buffer + n, debug_bufmax - n,
2271 "out[1].used %d \n", audio->out[1].used);
2272 n += scnprintf(buffer + n, debug_bufmax - n,
2273 "buffer_refresh %d \n", audio->buf_refresh);
2274 n += scnprintf(buffer + n, debug_bufmax - n,
2275 "read_next %d \n", audio->read_next);
2276 n += scnprintf(buffer + n, debug_bufmax - n,
2277 "fill_next %d \n", audio->fill_next);
2278 for (i = 0; i < audio->pcm_buf_count; i++)
2279 n += scnprintf(buffer + n, debug_bufmax - n,
2280 "in[%d].size %d \n", i, audio->in[i].used);
2281 buffer[n] = 0;
2282 return simple_read_from_buffer(buf, count, ppos, buffer, n);
2283}
2284
2285static const struct file_operations audmp3_debug_fops = {
2286 .read = audmp3_debug_read,
2287 .open = audmp3_debug_open,
2288};
2289#endif
2290
2291static int audio_open(struct inode *inode, struct file *file)
2292{
2293
2294 struct audio *audio = NULL;
2295 int rc, i, dec_attrb, decid;
2296 struct audmp3_event *e_node = NULL;
2297 unsigned pmem_sz = DMASZ_MAX;
2298#ifdef CONFIG_DEBUG_FS
2299 /* 4 bytes represents decoder number, 1 byte for terminate string */
2300 char name[sizeof "msm_mp3_" + 5];
2301#endif
2302
2303 /* Allocate audio instance, set to zero */
2304 audio = kzalloc(sizeof(struct audio), GFP_KERNEL);
2305 if (!audio) {
2306 MM_ERR("no memory to allocate audio instance \n");
2307 rc = -ENOMEM;
2308 goto done;
2309 }
2310 MM_INFO("audio instance 0x%08x created\n", (int)audio);
2311
2312 /* Allocate the decoder */
2313 dec_attrb = AUDDEC_DEC_MP3;
2314 if ((file->f_mode & FMODE_WRITE) &&
2315 (file->f_mode & FMODE_READ)) {
2316 dec_attrb |= MSM_AUD_MODE_NONTUNNEL;
2317 audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK;
2318 } else if ((file->f_mode & FMODE_WRITE) &&
2319 !(file->f_mode & FMODE_READ)) {
2320 dec_attrb |= MSM_AUD_MODE_TUNNEL;
2321 audio->pcm_feedback = TUNNEL_MODE_PLAYBACK;
2322 } else {
2323 kfree(audio);
2324 rc = -EACCES;
2325 goto done;
2326 }
2327
2328 decid = audpp_adec_alloc(dec_attrb, &audio->module_name,
2329 &audio->queue_id);
2330 if (decid < 0) {
2331 MM_ERR("No free decoder available, freeing instance 0x%08x\n",
2332 (int)audio);
2333 rc = -ENODEV;
2334 kfree(audio);
2335 goto done;
2336 }
2337 audio->dec_id = decid & MSM_AUD_DECODER_MASK;
2338
2339 /* AIO interface */
2340 if (file->f_flags & O_NONBLOCK) {
Santosh Mardifdc227a2011-07-11 17:20:34 +05302341 MM_DBG("set to aio interface\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002342 audio->drv_status |= ADRV_STATUS_AIO_INTF;
2343 audio->drv_ops.pcm_buf_update = audmp3_async_pcm_buf_update;
2344 audio->drv_ops.buffer_refresh = audmp3_async_buffer_refresh;
2345 audio->drv_ops.send_data = audmp3_async_send_data;
2346 audio->drv_ops.out_flush = audmp3_async_flush;
2347 audio->drv_ops.in_flush = audmp3_async_flush_pcm_buf;
2348 audio->drv_ops.fsync = audmp3_async_fsync;
2349 } else {
Santosh Mardifdc227a2011-07-11 17:20:34 +05302350 MM_DBG("set to std io interface\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002351 while (pmem_sz >= DMASZ_MIN) {
Santosh Mardifdc227a2011-07-11 17:20:34 +05302352 MM_DBG("pmemsz = %d\n", pmem_sz);
2353 audio->phys = allocate_contiguous_ebi_nomap(pmem_sz,
2354 SZ_4K);
2355 if (audio->phys) {
2356 audio->map_v_write = msm_subsystem_map_buffer(
2357 audio->phys, pmem_sz,
2358 MSM_SUBSYSTEM_MAP_KADDR
2359 , NULL, 0);
2360 if (IS_ERR(audio->map_v_write)) {
2361 MM_ERR("failed to map write physical"
2362 " address , freeing instance"
2363 "0x%08x\n", (int)audio);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002364 rc = -ENOMEM;
Santosh Mardifdc227a2011-07-11 17:20:34 +05302365 free_contiguous_memory_by_paddr(
2366 audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002367 audpp_adec_free(audio->dec_id);
2368 kfree(audio);
2369 goto done;
2370 }
Santosh Mardifdc227a2011-07-11 17:20:34 +05302371 audio->data = audio->map_v_write->vaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002372 MM_DBG("write buf: phy addr 0x%08x kernel addr\
2373 0x%08x\n", audio->phys,\
2374 (int)audio->data);
2375 break;
2376 } else if (pmem_sz == DMASZ_MIN) {
2377 MM_ERR("could not allocate write buffers, \
2378 freeing instance 0x%08x\n",
2379 (int)audio);
2380 rc = -ENOMEM;
2381 audpp_adec_free(audio->dec_id);
2382 kfree(audio);
2383 goto done;
2384 } else
2385 pmem_sz >>= 1;
2386 }
2387 audio->out_dma_sz = pmem_sz;
2388 audio->drv_ops.pcm_buf_update = audio_update_pcm_buf_entry;
2389 audio->drv_ops.buffer_refresh = audplay_buffer_refresh;
2390 audio->drv_ops.send_data = audplay_send_data;
2391 audio->drv_ops.out_flush = audio_flush;
2392 audio->drv_ops.in_flush = audio_flush_pcm_buf;
2393 audio->drv_ops.fsync = audmp3_sync_fsync;
2394 audio->out[0].data = audio->data + 0;
2395 audio->out[0].addr = audio->phys + 0;
2396 audio->out[0].size = (audio->out_dma_sz >> 1);
2397
2398 audio->out[1].data = audio->data + audio->out[0].size;
2399 audio->out[1].addr = audio->phys + audio->out[0].size;
2400 audio->out[1].size = audio->out[0].size;
2401 }
2402
2403 rc = msm_adsp_get(audio->module_name, &audio->audplay,
2404 &audplay_adsp_ops, audio);
2405
2406 if (rc) {
2407 MM_ERR("failed to get %s module freeing instance 0x%08x\n",
2408 audio->module_name, (int)audio);
2409 goto err;
2410 }
2411
2412 /* Initialize all locks of audio instance */
2413 mutex_init(&audio->lock);
2414 mutex_init(&audio->write_lock);
2415 mutex_init(&audio->read_lock);
2416 mutex_init(&audio->get_event_lock);
2417 spin_lock_init(&audio->dsp_lock);
2418 init_waitqueue_head(&audio->write_wait);
2419 init_waitqueue_head(&audio->read_wait);
2420 INIT_LIST_HEAD(&audio->out_queue);
2421 INIT_LIST_HEAD(&audio->in_queue);
2422 INIT_LIST_HEAD(&audio->pmem_region_queue);
2423 INIT_LIST_HEAD(&audio->free_event_queue);
2424 INIT_LIST_HEAD(&audio->event_queue);
2425 init_waitqueue_head(&audio->wait);
2426 init_waitqueue_head(&audio->event_wait);
2427 spin_lock_init(&audio->event_queue_lock);
2428 init_waitqueue_head(&audio->avsync_wait);
2429
2430 audio->out_sample_rate = 44100;
2431 audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
2432 audio->vol_pan.volume = 0x2000;
2433 audio->bitstream_error_threshold_value =
2434 BITSTREAM_ERROR_THRESHOLD_VALUE;
2435
2436 audio->drv_ops.out_flush(audio);
2437
2438 file->private_data = audio;
2439 audio->opened = 1;
2440
2441 audio->device_events = AUDDEV_EVT_DEV_RDY
2442 |AUDDEV_EVT_DEV_RLS |
2443 AUDDEV_EVT_STREAM_VOL_CHG;
2444
2445 rc = auddev_register_evt_listner(audio->device_events,
2446 AUDDEV_CLNT_DEC,
2447 audio->dec_id,
2448 mp3_listner,
2449 (void *)audio);
2450 if (rc) {
2451 MM_ERR("%s: failed to register listner\n", __func__);
2452 goto event_err;
2453 }
2454
2455#ifdef CONFIG_DEBUG_FS
2456 snprintf(name, sizeof name, "msm_mp3_%04x", audio->dec_id);
2457 audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
2458 NULL, (void *) audio, &audmp3_debug_fops);
2459
2460 if (IS_ERR(audio->dentry))
2461 MM_DBG("debugfs_create_file failed\n");
2462#endif
2463#ifdef CONFIG_HAS_EARLYSUSPEND
2464 audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
2465 audio->suspend_ctl.node.resume = audmp3_resume;
2466 audio->suspend_ctl.node.suspend = audmp3_suspend;
2467 audio->suspend_ctl.audio = audio;
2468 register_early_suspend(&audio->suspend_ctl.node);
2469#endif
2470 for (i = 0; i < AUDMP3_EVENT_NUM; i++) {
2471 e_node = kmalloc(sizeof(struct audmp3_event), GFP_KERNEL);
2472 if (e_node)
2473 list_add_tail(&e_node->list, &audio->free_event_queue);
2474 else {
2475 MM_ERR("event pkt alloc failed\n");
2476 break;
2477 }
2478 }
2479 memset(&audio->stream_info, 0, sizeof(struct msm_audio_bitstream_info));
2480 memset(&audio->bitstream_error_info, 0,
2481 sizeof(struct msm_audio_bitstream_info));
2482done:
2483 return rc;
2484event_err:
2485 msm_adsp_put(audio->audplay);
2486err:
2487 if (audio->data) {
Santosh Mardifdc227a2011-07-11 17:20:34 +05302488 msm_subsystem_unmap_buffer(audio->map_v_write);
2489 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002490 }
2491 audpp_adec_free(audio->dec_id);
2492 kfree(audio);
2493 return rc;
2494}
2495
2496static const struct file_operations audio_mp3_fops = {
2497 .owner = THIS_MODULE,
2498 .open = audio_open,
2499 .release = audio_release,
2500 .read = audio_read,
2501 .write = audio_write,
2502 .unlocked_ioctl = audio_ioctl,
2503 .fsync = audmp3_fsync,
2504};
2505
2506struct miscdevice audio_mp3_misc = {
2507 .minor = MISC_DYNAMIC_MINOR,
2508 .name = "msm_mp3",
2509 .fops = &audio_mp3_fops,
2510};
2511
2512static int __init audio_init(void)
2513{
2514 return misc_register(&audio_mp3_misc);
2515}
2516
2517static void __exit audio_exit(void)
2518{
2519 misc_deregister(&audio_mp3_misc);
2520}
2521
2522module_init(audio_init);
2523module_exit(audio_exit);
2524
2525MODULE_DESCRIPTION("MSM MP3 driver");
2526MODULE_LICENSE("GPL v2");