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