blob: b17cddabc3e919f83afa8782b966ab52e1b2b3fa [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* audio_wma.c - wma audio decoder driver
2 *
Manish Dewangana4f1df02012-02-08 17:06:54 +05303 * Copyright (c) 2009, 2011-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004 *
5 * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c
6 *
7 * Copyright (C) 2008 Google, Inc.
8 * Copyright (C) 2008 HTC Corporation
9 *
10 * All source code in this file is licensed under the following license except
11 * where indicated.
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License version 2 as published
15 * by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * See the GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, you can find it at http://www.fsf.org
24 */
25
Santosh Mardi0be3b8e2011-07-06 10:00:21 +053026#include <asm/atomic.h>
27#include <asm/ioctls.h>
28
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070029#include <linux/module.h>
30#include <linux/fs.h>
31#include <linux/miscdevice.h>
32#include <linux/uaccess.h>
33#include <linux/kthread.h>
34#include <linux/wait.h>
35#include <linux/dma-mapping.h>
36#include <linux/debugfs.h>
37#include <linux/delay.h>
38#include <linux/list.h>
39#include <linux/earlysuspend.h>
40#include <linux/android_pmem.h>
41#include <linux/slab.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070042#include <linux/msm_audio.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070043#include <linux/msm_audio_wma.h>
Santosh Mardi0be3b8e2011-07-06 10:00:21 +053044#include <linux/memory_alloc.h>
45
46#include <mach/msm_adsp.h>
47#include <mach/iommu.h>
48#include <mach/iommu_domains.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070049#include <mach/qdsp5/qdsp5audppcmdi.h>
50#include <mach/qdsp5/qdsp5audppmsg.h>
51#include <mach/qdsp5/qdsp5audplaycmdi.h>
52#include <mach/qdsp5/qdsp5audplaymsg.h>
53#include <mach/qdsp5/qdsp5rmtcmdi.h>
54#include <mach/debug_mm.h>
Santosh Mardi0be3b8e2011-07-06 10:00:21 +053055#include <mach/msm_memtypes.h>
56
57#include "audmgr.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070058
59/* Size must be power of 2 */
60#define BUFSZ_MAX 2062 /* Includes meta in size */
61#define BUFSZ_MIN 1038 /* Includes meta in size */
62#define DMASZ_MAX (BUFSZ_MAX * 2)
63#define DMASZ_MIN (BUFSZ_MIN * 2)
64
65#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF
66#define AUDDEC_DEC_WMA 4
67
68#define PCM_BUFSZ_MIN 8216 /* Hold one stereo WMA frame and meta out*/
69#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most
70 but support 2 buffers currently */
71#define ROUTING_MODE_FTRT 1
72#define ROUTING_MODE_RT 2
73/* Decoder status received from AUDPPTASK */
74#define AUDPP_DEC_STATUS_SLEEP 0
75#define AUDPP_DEC_STATUS_INIT 1
76#define AUDPP_DEC_STATUS_CFG 2
77#define AUDPP_DEC_STATUS_PLAY 3
78
79#define AUDWMA_METAFIELD_MASK 0xFFFF0000
80#define AUDWMA_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */
81#define AUDWMA_EOS_FLG_MASK 0x01
82#define AUDWMA_EOS_NONE 0x0 /* No EOS detected */
83#define AUDWMA_EOS_SET 0x1 /* EOS set in meta field */
84
85#define AUDWMA_EVENT_NUM 10 /* Default number of pre-allocated event packets */
86
87struct buffer {
88 void *data;
89 unsigned size;
90 unsigned used; /* Input usage actual DSP produced PCM size */
91 unsigned addr;
92 unsigned short mfield_sz; /*only useful for data has meta field */
93};
94
95#ifdef CONFIG_HAS_EARLYSUSPEND
96struct audwma_suspend_ctl {
97 struct early_suspend node;
98 struct audio *audio;
99};
100#endif
101
102struct audwma_event{
103 struct list_head list;
104 int event_type;
105 union msm_audio_event_payload payload;
106};
107
108struct audio {
109 struct buffer out[2];
110
111 spinlock_t dsp_lock;
112
113 uint8_t out_head;
114 uint8_t out_tail;
115 uint8_t out_needed; /* number of buffers the dsp is waiting for */
116 unsigned out_dma_sz;
117
118 atomic_t out_bytes;
119
120 struct mutex lock;
121 struct mutex write_lock;
122 wait_queue_head_t write_wait;
123
124 /* Host PCM section */
125 struct buffer in[PCM_BUF_MAX_COUNT];
126 struct mutex read_lock;
127 wait_queue_head_t read_wait; /* Wait queue for read */
128 char *read_data; /* pointer to reader buffer */
129 int32_t read_phys; /* physical address of reader buffer */
130 uint8_t read_next; /* index to input buffers to be read next */
131 uint8_t fill_next; /* index to buffer that DSP should be filling */
132 uint8_t pcm_buf_count; /* number of pcm buffer allocated */
133 /* ---- End of Host PCM section */
134
135 struct msm_adsp_module *audplay;
136
137 /* configuration to use on next enable */
138 uint32_t out_sample_rate;
139 uint32_t out_channel_mode;
140
141 struct msm_audio_wma_config wma_config;
142 struct audmgr audmgr;
143
144 /* data allocated for various buffers */
145 char *data;
146 int32_t phys; /* physical address of write buffer */
Laura Abbott35111d32012-04-27 18:41:48 -0700147 void *map_v_read;
148 void *map_v_write;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700149
150 int mfield; /* meta field embedded in data */
151 int rflush; /* Read flush */
152 int wflush; /* Write flush */
153 int opened;
154 int enabled;
155 int running;
156 int stopped; /* set when stopped, cleared on flush */
157 int pcm_feedback;
158 int buf_refresh;
159 int rmt_resource_released;
160 int teos; /* valid only if tunnel mode & no data left for decoder */
161 enum msm_aud_decoder_state dec_state; /* Represents decoder state */
162 int reserved; /* A byte is being reserved */
163 char rsv_byte; /* Handle odd length user data */
164
165 const char *module_name;
166 unsigned queue_id;
167 uint16_t dec_id;
168 uint32_t read_ptr_offset;
169
170#ifdef CONFIG_HAS_EARLYSUSPEND
171 struct audwma_suspend_ctl suspend_ctl;
172#endif
173
174#ifdef CONFIG_DEBUG_FS
175 struct dentry *dentry;
176#endif
177
178 wait_queue_head_t wait;
179 struct list_head free_event_queue;
180 struct list_head event_queue;
181 wait_queue_head_t event_wait;
182 spinlock_t event_queue_lock;
183 struct mutex get_event_lock;
184 int event_abort;
185
186 int eq_enable;
187 int eq_needs_commit;
188 audpp_cmd_cfg_object_params_eqalizer eq;
189 audpp_cmd_cfg_object_params_volume vol_pan;
190};
191
192static int auddec_dsp_config(struct audio *audio, int enable);
193static void audpp_cmd_cfg_adec_params(struct audio *audio);
194static void audpp_cmd_cfg_routing_mode(struct audio *audio);
195static void audplay_send_data(struct audio *audio, unsigned needed);
196static void audplay_config_hostpcm(struct audio *audio);
197static void audplay_buffer_refresh(struct audio *audio);
198static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
199#ifdef CONFIG_HAS_EARLYSUSPEND
200static void audwma_post_event(struct audio *audio, int type,
201 union msm_audio_event_payload payload);
202#endif
203
204static int rmt_put_resource(struct audio *audio)
205{
206 struct aud_codec_config_cmd cmd;
207 unsigned short client_idx;
208
209 cmd.cmd_id = RM_CMD_AUD_CODEC_CFG;
210 cmd.client_id = RM_AUD_CLIENT_ID;
211 cmd.task_id = audio->dec_id;
212 cmd.enable = RMT_DISABLE;
213 cmd.dec_type = AUDDEC_DEC_WMA;
214 client_idx = ((cmd.client_id << 8) | cmd.task_id);
215
216 return put_adsp_resource(client_idx, &cmd, sizeof(cmd));
217}
218
219static int rmt_get_resource(struct audio *audio)
220{
221 struct aud_codec_config_cmd cmd;
222 unsigned short client_idx;
223
224 cmd.cmd_id = RM_CMD_AUD_CODEC_CFG;
225 cmd.client_id = RM_AUD_CLIENT_ID;
226 cmd.task_id = audio->dec_id;
227 cmd.enable = RMT_ENABLE;
228 cmd.dec_type = AUDDEC_DEC_WMA;
229 client_idx = ((cmd.client_id << 8) | cmd.task_id);
230
231 return get_adsp_resource(client_idx, &cmd, sizeof(cmd));
232}
233
234/* must be called with audio->lock held */
235static int audio_enable(struct audio *audio)
236{
237 struct audmgr_config cfg;
238 int rc;
239
240 MM_DBG("\n"); /* Macro prints the file name and function */
241 if (audio->enabled)
242 return 0;
243
244 if (audio->rmt_resource_released == 1) {
245 audio->rmt_resource_released = 0;
246 rc = rmt_get_resource(audio);
247 if (rc) {
248 MM_ERR("ADSP resources are not available for WMA \
249 session 0x%08x on decoder: %d\n Ignoring \
250 error and going ahead with the playback\n",
251 (int)audio, audio->dec_id);
252 }
253 }
254
255 audio->dec_state = MSM_AUD_DECODER_STATE_NONE;
256 audio->out_tail = 0;
257 audio->out_needed = 0;
258
259 if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
260 cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
261 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
262 cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
263 cfg.codec = RPC_AUD_DEF_CODEC_WMA;
264 cfg.snd_method = RPC_SND_METHOD_MIDI;
265
266 rc = audmgr_enable(&audio->audmgr, &cfg);
267 if (rc < 0)
268 return rc;
269 }
270
271 if (msm_adsp_enable(audio->audplay)) {
272 MM_ERR("msm_adsp_enable(audplay) failed\n");
273 if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
274 audmgr_disable(&audio->audmgr);
275 return -ENODEV;
276 }
277
278 if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
279 MM_ERR("audpp_enable() failed\n");
280 msm_adsp_disable(audio->audplay);
281 if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
282 audmgr_disable(&audio->audmgr);
283 return -ENODEV;
284 }
285
286 audio->enabled = 1;
287 return 0;
288}
289
290/* must be called with audio->lock held */
291static int audio_disable(struct audio *audio)
292{
293 int rc = 0;
294 MM_DBG("\n"); /* Macro prints the file name and function */
295 if (audio->enabled) {
296 audio->enabled = 0;
297 audio->dec_state = MSM_AUD_DECODER_STATE_NONE;
298 auddec_dsp_config(audio, 0);
299 rc = wait_event_interruptible_timeout(audio->wait,
300 audio->dec_state != MSM_AUD_DECODER_STATE_NONE,
301 msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS));
302 if (rc == 0)
303 rc = -ETIMEDOUT;
304 else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE)
305 rc = -EFAULT;
306 else
307 rc = 0;
Manish Dewangan89a9f232012-02-09 17:14:40 +0530308 audio->stopped = 1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700309 wake_up(&audio->write_wait);
310 wake_up(&audio->read_wait);
311 msm_adsp_disable(audio->audplay);
312 audpp_disable(audio->dec_id, audio);
313 if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
314 audmgr_disable(&audio->audmgr);
315 audio->out_needed = 0;
316 rmt_put_resource(audio);
317 audio->rmt_resource_released = 1;
318 }
319 return rc;
320}
321
322/* ------------------- dsp --------------------- */
323static void audio_update_pcm_buf_entry(struct audio *audio,
324 uint32_t *payload)
325{
326 uint8_t index;
327 unsigned long flags;
328
329 if (audio->rflush)
330 return;
331
332 spin_lock_irqsave(&audio->dsp_lock, flags);
333 for (index = 0; index < payload[1]; index++) {
334 if (audio->in[audio->fill_next].addr ==
335 payload[2 + index * 2]) {
336 MM_DBG("audio_update_pcm_buf_entry: \
337 in[%d] ready\n", audio->fill_next);
338 audio->in[audio->fill_next].used =
339 payload[3 + index * 2];
340 if ((++audio->fill_next) == audio->pcm_buf_count)
341 audio->fill_next = 0;
342 } else {
343 MM_ERR("audio_update_pcm_buf_entry: \
344 expected=%x ret=%x\n",
345 audio->in[audio->fill_next].addr,
346 payload[1 + index * 2]);
347 break;
348 }
349 }
350 if (audio->in[audio->fill_next].used == 0) {
351 audplay_buffer_refresh(audio);
352 } else {
353 MM_DBG("read cannot keep up\n");
354 audio->buf_refresh = 1;
355 }
356 wake_up(&audio->read_wait);
357 spin_unlock_irqrestore(&audio->dsp_lock, flags);
358}
359
360static void audplay_dsp_event(void *data, unsigned id, size_t len,
361 void (*getevent) (void *ptr, size_t len))
362{
363 struct audio *audio = data;
364 uint32_t msg[28];
365
366 getevent(msg, sizeof(msg));
367
368 MM_DBG("msg_id=%x\n", id);
369
370 switch (id) {
371 case AUDPLAY_MSG_DEC_NEEDS_DATA:
372 audplay_send_data(audio, 1);
373 break;
374
375 case AUDPLAY_MSG_BUFFER_UPDATE:
376 audio_update_pcm_buf_entry(audio, msg);
377 break;
378
379 case ADSP_MESSAGE_ID:
380 MM_DBG("Received ADSP event: module enable(audplaytask)\n");
381 break;
382
383 default:
384 MM_ERR("unexpected message from decoder \n");
385 break;
386 }
387}
388
389static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
390{
391 struct audio *audio = private;
392
393 switch (id) {
394 case AUDPP_MSG_STATUS_MSG:{
395 unsigned status = msg[1];
396
397 switch (status) {
398 case AUDPP_DEC_STATUS_SLEEP: {
399 uint16_t reason = msg[2];
400 MM_DBG("decoder status:sleep reason = \
401 0x%04x\n", reason);
402 if ((reason == AUDPP_MSG_REASON_MEM)
403 || (reason ==
404 AUDPP_MSG_REASON_NODECODER)) {
405 audio->dec_state =
406 MSM_AUD_DECODER_STATE_FAILURE;
407 wake_up(&audio->wait);
408 } else if (reason == AUDPP_MSG_REASON_NONE) {
409 /* decoder is in disable state */
410 audio->dec_state =
411 MSM_AUD_DECODER_STATE_CLOSE;
412 wake_up(&audio->wait);
413 }
414 break;
415 }
416 case AUDPP_DEC_STATUS_INIT:
417 MM_DBG("decoder status: init\n");
418 if (audio->pcm_feedback)
419 audpp_cmd_cfg_routing_mode(audio);
420 else
421 audpp_cmd_cfg_adec_params(audio);
422 break;
423
424 case AUDPP_DEC_STATUS_CFG:
425 MM_DBG("decoder status: cfg\n");
426 break;
427 case AUDPP_DEC_STATUS_PLAY:
428 MM_DBG("decoder status: play\n");
429 if (audio->pcm_feedback) {
430 audplay_config_hostpcm(audio);
431 audplay_buffer_refresh(audio);
432 }
433 audio->dec_state =
434 MSM_AUD_DECODER_STATE_SUCCESS;
435 wake_up(&audio->wait);
436 break;
437 default:
438 MM_ERR("unknown decoder status\n");
439 }
440 break;
441 }
442 case AUDPP_MSG_CFG_MSG:
443 if (msg[0] == AUDPP_MSG_ENA_ENA) {
444 MM_DBG("CFG_MSG ENABLE\n");
445 auddec_dsp_config(audio, 1);
446 audio->out_needed = 0;
447 audio->running = 1;
448 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan);
449 audpp_dsp_set_eq(audio->dec_id, audio->eq_enable,
450 &audio->eq);
451 audpp_avsync(audio->dec_id, 22050);
452 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
453 MM_DBG("CFG_MSG DISABLE\n");
454 audpp_avsync(audio->dec_id, 0);
455 audio->running = 0;
456 } else {
457 MM_DBG("CFG_MSG %d?\n", msg[0]);
458 }
459 break;
460 case AUDPP_MSG_ROUTING_ACK:
461 MM_DBG("ROUTING_ACK mode=%d\n", msg[1]);
462 audpp_cmd_cfg_adec_params(audio);
463 break;
464
465 case AUDPP_MSG_FLUSH_ACK:
466 MM_DBG("FLUSH_ACK\n");
467 audio->wflush = 0;
468 audio->rflush = 0;
469 wake_up(&audio->write_wait);
470 if (audio->pcm_feedback)
471 audplay_buffer_refresh(audio);
Phani Kumar Alladaee940eb2012-05-10 11:13:04 +0530472 break;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700473 case AUDPP_MSG_PCMDMAMISSED:
474 MM_DBG("PCMDMAMISSED\n");
475 audio->teos = 1;
476 wake_up(&audio->write_wait);
477 break;
478
479 default:
480 MM_ERR("UNKNOWN (%d)\n", id);
481 }
482
483}
484
485static struct msm_adsp_ops audplay_adsp_ops_wma = {
486 .event = audplay_dsp_event,
487};
488
489#define audplay_send_queue0(audio, cmd, len) \
490 msm_adsp_write(audio->audplay, audio->queue_id, \
491 cmd, len)
492
493static int auddec_dsp_config(struct audio *audio, int enable)
494{
495 u16 cfg_dec_cmd[AUDPP_CMD_CFG_DEC_TYPE_LEN / sizeof(unsigned short)];
496
497 memset(cfg_dec_cmd, 0, sizeof(cfg_dec_cmd));
498 cfg_dec_cmd[0] = AUDPP_CMD_CFG_DEC_TYPE;
499 if (enable)
500 cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC |
501 AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_WMA;
502 else
503 cfg_dec_cmd[1 + audio->dec_id] = AUDPP_CMD_UPDATDE_CFG_DEC |
504 AUDPP_CMD_DIS_DEC_V;
505
506 return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd));
507}
508
509static void audpp_cmd_cfg_adec_params(struct audio *audio)
510{
511 struct audpp_cmd_cfg_adec_params_wma cmd;
512
513 memset(&cmd, 0, sizeof(cmd));
514 cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
515 cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_WMA_LEN;
516 cmd.common.dec_id = audio->dec_id;
517 cmd.common.input_sampling_frequency = audio->out_sample_rate;
518
519 /*
520 * Test done for sample with the following configuration
521 * armdatareqthr = 1262
522 * channelsdecoded = 1(MONO)/2(STEREO)
523 * wmabytespersec = Tested with 6003 Bytes per sec
524 * wmasamplingfreq = 44100
525 * wmaencoderopts = 31
526 */
527
528 cmd.armdatareqthr = audio->wma_config.armdatareqthr;
529 cmd.channelsdecoded = audio->wma_config.channelsdecoded;
530 cmd.wmabytespersec = audio->wma_config.wmabytespersec;
531 cmd.wmasamplingfreq = audio->wma_config.wmasamplingfreq;
532 cmd.wmaencoderopts = audio->wma_config.wmaencoderopts;
533
534 audpp_send_queue2(&cmd, sizeof(cmd));
535}
536
537static void audpp_cmd_cfg_routing_mode(struct audio *audio)
538{
539 struct audpp_cmd_routing_mode cmd;
540
541 MM_DBG("\n"); /* Macro prints the file name and function */
542 memset(&cmd, 0, sizeof(cmd));
543 cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
544 cmd.object_number = audio->dec_id;
545 if (audio->pcm_feedback)
546 cmd.routing_mode = ROUTING_MODE_FTRT;
547 else
548 cmd.routing_mode = ROUTING_MODE_RT;
549
550 audpp_send_queue1(&cmd, sizeof(cmd));
551}
552
553static void audplay_buffer_refresh(struct audio *audio)
554{
555 struct audplay_cmd_buffer_refresh refresh_cmd;
556
557 refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
558 refresh_cmd.num_buffers = 1;
559 refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
560 refresh_cmd.buf0_length = audio->in[audio->fill_next].size;
561 refresh_cmd.buf_read_count = 0;
562
563 MM_DBG("buf0_addr=%x buf0_len=%d\n",
564 refresh_cmd.buf0_address,
565 refresh_cmd.buf0_length);
566
567 (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
568}
569
570static void audplay_config_hostpcm(struct audio *audio)
571{
572 struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
573
574 MM_DBG("\n"); /* Macro prints the file name and function */
575 cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
576 cfg_cmd.max_buffers = audio->pcm_buf_count;
577 cfg_cmd.byte_swap = 0;
578 cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
579 cfg_cmd.feedback_frequency = 1;
580 cfg_cmd.partition_number = 0;
581
582 (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
583}
584
585
586static int audplay_dsp_send_data_avail(struct audio *audio,
587 unsigned idx, unsigned len)
588{
589 struct audplay_cmd_bitstream_data_avail_nt2 cmd;
590
591 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2;
592 if (audio->mfield)
593 cmd.decoder_id = AUDWMA_METAFIELD_MASK |
594 (audio->out[idx].mfield_sz >> 1);
595 else
596 cmd.decoder_id = audio->dec_id;
597 cmd.buf_ptr = audio->out[idx].addr;
598 cmd.buf_size = len/2;
599 cmd.partition_number = 0;
600 /* complete writes to the input buffer */
601 wmb();
602 return audplay_send_queue0(audio, &cmd, sizeof(cmd));
603}
604
605static void audplay_send_data(struct audio *audio, unsigned needed)
606{
607 struct buffer *frame;
608 unsigned long flags;
609
610 spin_lock_irqsave(&audio->dsp_lock, flags);
611 if (!audio->running)
612 goto done;
613
614 if (audio->wflush) {
615 audio->out_needed = 1;
616 goto done;
617 }
618
619 if (needed && !audio->wflush) {
620 /* We were called from the callback because the DSP
621 * requested more data. Note that the DSP does want
622 * more data, and if a buffer was in-flight, mark it
623 * as available (since the DSP must now be done with
624 * it).
625 */
626 audio->out_needed = 1;
627 frame = audio->out + audio->out_tail;
628 if (frame->used == 0xffffffff) {
629 MM_DBG("frame %d free\n", audio->out_tail);
630 frame->used = 0;
631 audio->out_tail ^= 1;
632 wake_up(&audio->write_wait);
633 }
634 }
635
636 if (audio->out_needed) {
637 /* If the DSP currently wants data and we have a
638 * buffer available, we will send it and reset
639 * the needed flag. We'll mark the buffer as in-flight
640 * so that it won't be recycled until the next buffer
641 * is requested
642 */
643
644 MM_DBG("\n"); /* Macro prints the file name and function */
645 frame = audio->out + audio->out_tail;
646 if (frame->used) {
647 BUG_ON(frame->used == 0xffffffff);
648 MM_DBG("frame %d busy\n", audio->out_tail);
649 audplay_dsp_send_data_avail(audio, audio->out_tail,
650 frame->used);
651 frame->used = 0xffffffff;
652 audio->out_needed = 0;
653 }
654 }
655done:
656 spin_unlock_irqrestore(&audio->dsp_lock, flags);
657}
658
659/* ------------------- device --------------------- */
660
661static void audio_flush(struct audio *audio)
662{
Manish Dewangana4f1df02012-02-08 17:06:54 +0530663 unsigned long flags;
664
665 spin_lock_irqsave(&audio->dsp_lock, flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700666 audio->out[0].used = 0;
667 audio->out[1].used = 0;
668 audio->out_head = 0;
669 audio->out_tail = 0;
670 audio->reserved = 0;
Manish Dewangana4f1df02012-02-08 17:06:54 +0530671 spin_unlock_irqrestore(&audio->dsp_lock, flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700672 atomic_set(&audio->out_bytes, 0);
673}
674
675static void audio_flush_pcm_buf(struct audio *audio)
676{
677 uint8_t index;
678
Manish Dewangana4f1df02012-02-08 17:06:54 +0530679 unsigned long flags;
680
681 spin_lock_irqsave(&audio->dsp_lock, flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700682 for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
683 audio->in[index].used = 0;
684 audio->buf_refresh = 0;
685 audio->read_next = 0;
686 audio->fill_next = 0;
Manish Dewangana4f1df02012-02-08 17:06:54 +0530687 spin_unlock_irqrestore(&audio->dsp_lock, flags);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700688}
689
690static void audio_ioport_reset(struct audio *audio)
691{
692 /* Make sure read/write thread are free from
693 * sleep and knowing that system is not able
694 * to process io request at the moment
695 */
696 wake_up(&audio->write_wait);
697 mutex_lock(&audio->write_lock);
698 audio_flush(audio);
699 mutex_unlock(&audio->write_lock);
700 wake_up(&audio->read_wait);
701 mutex_lock(&audio->read_lock);
702 audio_flush_pcm_buf(audio);
703 mutex_unlock(&audio->read_lock);
704}
705
706static int audwma_events_pending(struct audio *audio)
707{
708 unsigned long flags;
709 int empty;
710
711 spin_lock_irqsave(&audio->event_queue_lock, flags);
712 empty = !list_empty(&audio->event_queue);
713 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
714 return empty || audio->event_abort;
715}
716
717static void audwma_reset_event_queue(struct audio *audio)
718{
719 unsigned long flags;
720 struct audwma_event *drv_evt;
721 struct list_head *ptr, *next;
722
723 spin_lock_irqsave(&audio->event_queue_lock, flags);
724 list_for_each_safe(ptr, next, &audio->event_queue) {
725 drv_evt = list_first_entry(&audio->event_queue,
726 struct audwma_event, list);
727 list_del(&drv_evt->list);
728 kfree(drv_evt);
729 }
730 list_for_each_safe(ptr, next, &audio->free_event_queue) {
731 drv_evt = list_first_entry(&audio->free_event_queue,
732 struct audwma_event, list);
733 list_del(&drv_evt->list);
734 kfree(drv_evt);
735 }
736 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
737
738 return;
739}
740
741static long audwma_process_event_req(struct audio *audio, void __user *arg)
742{
743 long rc;
744 struct msm_audio_event usr_evt;
745 struct audwma_event *drv_evt = NULL;
746 int timeout;
747 unsigned long flags;
748
749 if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event)))
750 return -EFAULT;
751
752 timeout = (int) usr_evt.timeout_ms;
753
754 if (timeout > 0) {
755 rc = wait_event_interruptible_timeout(
756 audio->event_wait, audwma_events_pending(audio),
757 msecs_to_jiffies(timeout));
758 if (rc == 0)
759 return -ETIMEDOUT;
760 } else {
761 rc = wait_event_interruptible(
762 audio->event_wait, audwma_events_pending(audio));
763 }
764
765 if (rc < 0)
766 return rc;
767
768 if (audio->event_abort) {
769 audio->event_abort = 0;
770 return -ENODEV;
771 }
772
773 rc = 0;
774
775 spin_lock_irqsave(&audio->event_queue_lock, flags);
776 if (!list_empty(&audio->event_queue)) {
777 drv_evt = list_first_entry(&audio->event_queue,
778 struct audwma_event, list);
779 list_del(&drv_evt->list);
780 }
781
782 if (drv_evt) {
783 usr_evt.event_type = drv_evt->event_type;
784 usr_evt.event_payload = drv_evt->payload;
785 list_add_tail(&drv_evt->list, &audio->free_event_queue);
786 } else
787 rc = -1;
788 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
789
790 if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt)))
791 rc = -EFAULT;
792
793 return rc;
794}
795
796static int audio_enable_eq(struct audio *audio, int enable)
797{
798 if (audio->eq_enable == enable && !audio->eq_needs_commit)
799 return 0;
800
801 audio->eq_enable = enable;
802
803 if (audio->running) {
804 audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq);
805 audio->eq_needs_commit = 0;
806 }
807 return 0;
808}
809
810static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
811{
812 struct audio *audio = file->private_data;
813 int rc = -EINVAL;
814 unsigned long flags = 0;
815 uint16_t enable_mask;
816 int enable;
817 int prev_state;
818
819 MM_DBG("cmd = %d\n", cmd);
820
821 if (cmd == AUDIO_GET_STATS) {
822 struct msm_audio_stats stats;
823 stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
824 stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
825 if (copy_to_user((void *)arg, &stats, sizeof(stats)))
826 return -EFAULT;
827 return 0;
828 }
829
830 switch (cmd) {
831 case AUDIO_ENABLE_AUDPP:
832 if (copy_from_user(&enable_mask, (void *) arg,
833 sizeof(enable_mask))) {
834 rc = -EFAULT;
835 break;
836 }
837
838 spin_lock_irqsave(&audio->dsp_lock, flags);
839 enable = (enable_mask & EQ_ENABLE) ? 1 : 0;
840 audio_enable_eq(audio, enable);
841 spin_unlock_irqrestore(&audio->dsp_lock, flags);
842 rc = 0;
843 break;
844 case AUDIO_SET_VOLUME:
845 spin_lock_irqsave(&audio->dsp_lock, flags);
846 audio->vol_pan.volume = arg;
847 if (audio->running)
848 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan);
849 spin_unlock_irqrestore(&audio->dsp_lock, flags);
850 rc = 0;
851 break;
852
853 case AUDIO_SET_PAN:
854 spin_lock_irqsave(&audio->dsp_lock, flags);
855 audio->vol_pan.pan = arg;
856 if (audio->running)
857 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan);
858 spin_unlock_irqrestore(&audio->dsp_lock, flags);
859 rc = 0;
860 break;
861
862 case AUDIO_SET_EQ:
863 prev_state = audio->eq_enable;
864 audio->eq_enable = 0;
865 if (copy_from_user(&audio->eq.num_bands, (void *) arg,
866 sizeof(audio->eq) -
867 (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) {
868 rc = -EFAULT;
869 break;
870 }
871 audio->eq_enable = prev_state;
872 audio->eq_needs_commit = 1;
873 rc = 0;
874 break;
875 }
876
877 if (-EINVAL != rc)
878 return rc;
879
880 if (cmd == AUDIO_GET_EVENT) {
881 MM_DBG("AUDIO_GET_EVENT\n");
882 if (mutex_trylock(&audio->get_event_lock)) {
883 rc = audwma_process_event_req(audio,
884 (void __user *) arg);
885 mutex_unlock(&audio->get_event_lock);
886 } else
887 rc = -EBUSY;
888 return rc;
889 }
890
891 if (cmd == AUDIO_ABORT_GET_EVENT) {
892 audio->event_abort = 1;
893 wake_up(&audio->event_wait);
894 return 0;
895 }
896
897 mutex_lock(&audio->lock);
898 switch (cmd) {
899 case AUDIO_START:
900 MM_DBG("AUDIO_START\n");
901 rc = audio_enable(audio);
902 if (!rc) {
903 rc = wait_event_interruptible_timeout(audio->wait,
904 audio->dec_state != MSM_AUD_DECODER_STATE_NONE,
905 msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS));
906 MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc);
907
908 if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS)
909 rc = -ENODEV;
910 else
911 rc = 0;
912 }
913 break;
914 case AUDIO_STOP:
915 MM_DBG("AUDIO_STOP\n");
916 rc = audio_disable(audio);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700917 audio_ioport_reset(audio);
918 audio->stopped = 0;
919 break;
920 case AUDIO_FLUSH:
921 MM_DBG("AUDIO_FLUSH\n");
922 audio->rflush = 1;
923 audio->wflush = 1;
924 audio_ioport_reset(audio);
925 if (audio->running) {
926 audpp_flush(audio->dec_id);
927 rc = wait_event_interruptible(audio->write_wait,
928 !audio->wflush);
929 if (rc < 0) {
930 MM_ERR("AUDIO_FLUSH interrupted\n");
931 rc = -EINTR;
932 }
933 } else {
934 audio->rflush = 0;
935 audio->wflush = 0;
936 }
937 break;
938 case AUDIO_SET_CONFIG: {
939 struct msm_audio_config config;
940 if (copy_from_user(&config, (void *) arg, sizeof(config))) {
941 rc = -EFAULT;
942 break;
943 }
944 if (config.channel_count == 1) {
945 config.channel_count = AUDPP_CMD_PCM_INTF_MONO_V;
946 } else if (config.channel_count == 2) {
947 config.channel_count = AUDPP_CMD_PCM_INTF_STEREO_V;
948 } else {
949 rc = -EINVAL;
950 break;
951 }
952 audio->mfield = config.meta_field;
953 audio->out_sample_rate = config.sample_rate;
954 audio->out_channel_mode = config.channel_count;
955 rc = 0;
956 break;
957 }
958 case AUDIO_GET_CONFIG: {
959 struct msm_audio_config config;
960 config.buffer_size = (audio->out_dma_sz >> 1);
961 config.buffer_count = 2;
962 config.sample_rate = audio->out_sample_rate;
963 if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V)
964 config.channel_count = 1;
965 else
966 config.channel_count = 2;
967 config.meta_field = 0;
968 config.unused[0] = 0;
969 config.unused[1] = 0;
970 config.unused[2] = 0;
971 if (copy_to_user((void *) arg, &config, sizeof(config)))
972 rc = -EFAULT;
973 else
974 rc = 0;
975
976 break;
977 }
978 case AUDIO_GET_WMA_CONFIG:{
979 if (copy_to_user((void *)arg, &audio->wma_config,
980 sizeof(audio->wma_config)))
981 rc = -EFAULT;
982 else
983 rc = 0;
984 break;
985 }
986 case AUDIO_SET_WMA_CONFIG:{
987 struct msm_audio_wma_config usr_config;
988
989 if (copy_from_user
990 (&usr_config, (void *)arg,
991 sizeof(usr_config))) {
992 rc = -EFAULT;
993 break;
994 }
995
996 audio->wma_config = usr_config;
997 rc = 0;
998 break;
999 }
1000 case AUDIO_GET_PCM_CONFIG:{
1001 struct msm_audio_pcm_config config;
1002 config.pcm_feedback = audio->pcm_feedback;
1003 config.buffer_count = PCM_BUF_MAX_COUNT;
1004 config.buffer_size = PCM_BUFSZ_MIN;
1005 if (copy_to_user((void *)arg, &config,
1006 sizeof(config)))
1007 rc = -EFAULT;
1008 else
1009 rc = 0;
1010 break;
1011 }
1012 case AUDIO_SET_PCM_CONFIG:{
1013 struct msm_audio_pcm_config config;
1014 if (copy_from_user
1015 (&config, (void *)arg, sizeof(config))) {
1016 rc = -EFAULT;
1017 break;
1018 }
1019 if (config.pcm_feedback != audio->pcm_feedback) {
1020 MM_ERR("Not sufficient permission to"
1021 "change the playback mode\n");
1022 rc = -EACCES;
1023 break;
1024 }
1025 if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
1026 (config.buffer_count == 1))
1027 config.buffer_count = PCM_BUF_MAX_COUNT;
1028
1029 if (config.buffer_size < PCM_BUFSZ_MIN)
1030 config.buffer_size = PCM_BUFSZ_MIN;
1031
1032 /* Check if pcm feedback is required */
1033 if ((config.pcm_feedback) && (!audio->read_data)) {
1034 MM_DBG("allocate PCM buffer %d\n",
1035 config.buffer_count *
1036 config.buffer_size);
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301037 audio->read_phys =
1038 allocate_contiguous_ebi_nomap(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001039 config.buffer_size *
1040 config.buffer_count,
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301041 SZ_4K);
1042 if (!audio->read_phys) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001043 rc = -ENOMEM;
1044 break;
1045 }
Laura Abbott35111d32012-04-27 18:41:48 -07001046 audio->map_v_read = ioremap(
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301047 audio->read_phys,
1048 config.buffer_size *
Laura Abbott35111d32012-04-27 18:41:48 -07001049 config.buffer_count);
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301050 if (IS_ERR(audio->map_v_read)) {
1051 MM_ERR("map of read buf failed\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001052 rc = -ENOMEM;
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301053 free_contiguous_memory_by_paddr(
1054 audio->read_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001055 } else {
1056 uint8_t index;
1057 uint32_t offset = 0;
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301058 audio->read_data =
Laura Abbott35111d32012-04-27 18:41:48 -07001059 audio->map_v_read;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001060 audio->buf_refresh = 0;
1061 audio->pcm_buf_count =
1062 config.buffer_count;
1063 audio->read_next = 0;
1064 audio->fill_next = 0;
1065
1066 for (index = 0;
1067 index < config.buffer_count;
1068 index++) {
1069 audio->in[index].data =
1070 audio->read_data + offset;
1071 audio->in[index].addr =
1072 audio->read_phys + offset;
1073 audio->in[index].size =
1074 config.buffer_size;
1075 audio->in[index].used = 0;
1076 offset += config.buffer_size;
1077 }
1078 MM_DBG("read buf: phy addr \
1079 0x%08x kernel addr 0x%08x\n",
1080 audio->read_phys,
1081 (int)audio->read_data);
1082 rc = 0;
1083 }
1084 } else {
1085 rc = 0;
1086 }
1087 break;
1088 }
1089 case AUDIO_PAUSE:
1090 MM_DBG("AUDIO_PAUSE %ld\n", arg);
1091 rc = audpp_pause(audio->dec_id, (int) arg);
1092 break;
1093 default:
1094 rc = -EINVAL;
1095 }
1096 mutex_unlock(&audio->lock);
1097 return rc;
1098}
1099
1100/* Only useful in tunnel-mode */
1101static int audio_fsync(struct file *file, int datasync)
1102{
1103 struct audio *audio = file->private_data;
1104 struct buffer *frame;
1105 int rc = 0;
1106
1107 MM_DBG("\n"); /* Macro prints the file name and function */
1108
1109 if (!audio->running || audio->pcm_feedback) {
1110 rc = -EINVAL;
1111 goto done_nolock;
1112 }
1113
1114 mutex_lock(&audio->write_lock);
1115
1116 rc = wait_event_interruptible(audio->write_wait,
1117 (!audio->out[0].used &&
1118 !audio->out[1].used &&
1119 audio->out_needed) || audio->wflush);
1120
1121 if (rc < 0)
1122 goto done;
1123 else if (audio->wflush) {
1124 rc = -EBUSY;
1125 goto done;
1126 }
1127
1128 if (audio->reserved) {
1129 MM_DBG("send reserved byte\n");
1130 frame = audio->out + audio->out_tail;
1131 ((char *) frame->data)[0] = audio->rsv_byte;
1132 ((char *) frame->data)[1] = 0;
1133 frame->used = 2;
1134 audplay_send_data(audio, 0);
1135
1136 rc = wait_event_interruptible(audio->write_wait,
1137 (!audio->out[0].used &&
1138 !audio->out[1].used &&
1139 audio->out_needed) || audio->wflush);
1140
1141 if (rc < 0)
1142 goto done;
1143 else if (audio->wflush) {
1144 rc = -EBUSY;
1145 goto done;
1146 }
1147 }
1148
1149 /* pcm dmamiss message is sent continously
1150 * when decoder is starved so no race
1151 * condition concern
1152 */
1153 audio->teos = 0;
1154
1155 rc = wait_event_interruptible(audio->write_wait,
1156 audio->teos || audio->wflush);
1157
1158 if (audio->wflush)
1159 rc = -EBUSY;
1160
1161done:
1162 mutex_unlock(&audio->write_lock);
1163done_nolock:
1164 return rc;
1165}
1166
1167static ssize_t audio_read(struct file *file, char __user *buf, size_t count,
1168 loff_t *pos)
1169{
1170 struct audio *audio = file->private_data;
1171 const char __user *start = buf;
1172 int rc = 0;
1173
1174 if (!audio->pcm_feedback)
1175 return 0; /* PCM feedback is not enabled. Nothing to read */
1176
1177 mutex_lock(&audio->read_lock);
1178 MM_DBG("%d \n", count);
1179 while (count > 0) {
1180 rc = wait_event_interruptible(audio->read_wait,
1181 (audio->in[audio->read_next].used > 0) ||
1182 (audio->stopped) || (audio->rflush));
1183
1184 if (rc < 0)
1185 break;
1186
1187 if (audio->stopped || audio->rflush) {
1188 rc = -EBUSY;
1189 break;
1190 }
1191
1192 if (count < audio->in[audio->read_next].used) {
1193 /* Read must happen in frame boundary. Since driver
1194 does not know frame size, read count must be greater
1195 or equal to size of PCM samples */
1196 MM_DBG("audio_read: no partial frame done reading\n");
1197 break;
1198 } else {
1199 MM_DBG("audio_read: read from in[%d]\n",
1200 audio->read_next);
1201 /* order reads from the output buffer */
1202 rmb();
1203 if (copy_to_user
1204 (buf, audio->in[audio->read_next].data,
1205 audio->in[audio->read_next].used)) {
1206 MM_ERR("invalid addr %x \n", (unsigned int)buf);
1207 rc = -EFAULT;
1208 break;
1209 }
1210 count -= audio->in[audio->read_next].used;
1211 buf += audio->in[audio->read_next].used;
1212 audio->in[audio->read_next].used = 0;
1213 if ((++audio->read_next) == audio->pcm_buf_count)
1214 audio->read_next = 0;
1215 break; /* Force to exit while loop
1216 * to prevent output thread
1217 * sleep too long if data is
1218 * not ready at this moment.
1219 */
1220 }
1221 }
1222
1223 /* don't feed output buffer to HW decoder during flushing
1224 * buffer refresh command will be sent once flush completes
1225 * send buf refresh command here can confuse HW decoder
1226 */
1227 if (audio->buf_refresh && !audio->rflush) {
1228 audio->buf_refresh = 0;
1229 MM_DBG("kick start pcm feedback again\n");
1230 audplay_buffer_refresh(audio);
1231 }
1232
1233 mutex_unlock(&audio->read_lock);
1234
1235 if (buf > start)
1236 rc = buf - start;
1237
1238 MM_DBG("read %d bytes\n", rc);
1239 return rc;
1240}
1241
1242static int audwma_process_eos(struct audio *audio,
1243 const char __user *buf_start, unsigned short mfield_size)
1244{
1245 int rc = 0;
1246 struct buffer *frame;
1247 char *buf_ptr;
1248
1249 if (audio->reserved) {
1250 MM_DBG("flush reserve byte\n");
1251 frame = audio->out + audio->out_head;
1252 buf_ptr = frame->data;
1253 rc = wait_event_interruptible(audio->write_wait,
1254 (frame->used == 0)
1255 || (audio->stopped)
1256 || (audio->wflush));
1257 if (rc < 0)
1258 goto done;
1259 if (audio->stopped || audio->wflush) {
1260 rc = -EBUSY;
1261 goto done;
1262 }
1263
1264 buf_ptr[0] = audio->rsv_byte;
1265 buf_ptr[1] = 0;
1266 audio->out_head ^= 1;
1267 frame->mfield_sz = 0;
1268 frame->used = 2;
1269 audio->reserved = 0;
1270 audplay_send_data(audio, 0);
1271 }
1272
1273 frame = audio->out + audio->out_head;
1274
1275 rc = wait_event_interruptible(audio->write_wait,
1276 (audio->out_needed &&
1277 audio->out[0].used == 0 &&
1278 audio->out[1].used == 0)
1279 || (audio->stopped)
1280 || (audio->wflush));
1281
1282 if (rc < 0)
1283 goto done;
1284 if (audio->stopped || audio->wflush) {
1285 rc = -EBUSY;
1286 goto done;
1287 }
1288
1289 if (copy_from_user(frame->data, buf_start, mfield_size)) {
1290 rc = -EFAULT;
1291 goto done;
1292 }
1293
1294 frame->mfield_sz = mfield_size;
1295 audio->out_head ^= 1;
1296 frame->used = mfield_size;
1297 audplay_send_data(audio, 0);
1298done:
1299 return rc;
1300}
1301
1302static ssize_t audio_write(struct file *file, const char __user *buf,
1303 size_t count, loff_t *pos)
1304{
1305 struct audio *audio = file->private_data;
1306 const char __user *start = buf;
1307 struct buffer *frame;
1308 size_t xfer;
1309 char *cpy_ptr;
1310 int rc = 0, eos_condition = AUDWMA_EOS_NONE;
1311 unsigned dsize;
1312 unsigned short mfield_size = 0;
1313
1314 MM_DBG("cnt=%d\n", count);
1315
1316 mutex_lock(&audio->write_lock);
1317 while (count > 0) {
1318 frame = audio->out + audio->out_head;
1319 cpy_ptr = frame->data;
1320 dsize = 0;
1321 rc = wait_event_interruptible(audio->write_wait,
1322 (frame->used == 0)
1323 || (audio->stopped)
1324 || (audio->wflush));
1325 if (rc < 0)
1326 break;
1327 if (audio->stopped || audio->wflush) {
1328 rc = -EBUSY;
1329 break;
1330 }
1331 if (audio->mfield) {
1332 if (buf == start) {
1333 /* Processing beginning of user buffer */
1334 if (__get_user(mfield_size,
1335 (unsigned short __user *) buf)) {
1336 rc = -EFAULT;
1337 break;
1338 } else if (mfield_size > count) {
1339 rc = -EINVAL;
1340 break;
1341 }
1342 MM_DBG("audio_write: mf offset_val %x\n",
1343 mfield_size);
1344 if (copy_from_user(cpy_ptr, buf, mfield_size)) {
1345 rc = -EFAULT;
1346 break;
1347 }
1348 /* Check if EOS flag is set and buffer has
1349 * contains just meta field
1350 */
1351 if (cpy_ptr[AUDWMA_EOS_FLG_OFFSET] &
1352 AUDWMA_EOS_FLG_MASK) {
1353 MM_DBG("audio_write: EOS SET\n");
1354 eos_condition = AUDWMA_EOS_SET;
1355 if (mfield_size == count) {
1356 buf += mfield_size;
1357 break;
1358 } else
1359 cpy_ptr[AUDWMA_EOS_FLG_OFFSET]
1360 &= ~AUDWMA_EOS_FLG_MASK;
1361 }
1362 cpy_ptr += mfield_size;
1363 count -= mfield_size;
1364 dsize += mfield_size;
1365 buf += mfield_size;
1366 } else {
1367 mfield_size = 0;
1368 MM_DBG("audio_write: continuous buffer\n");
1369 }
1370 frame->mfield_sz = mfield_size;
1371 }
1372
1373 if (audio->reserved) {
1374 MM_DBG("append reserved byte %x\n", audio->rsv_byte);
1375 *cpy_ptr = audio->rsv_byte;
1376 xfer = (count > ((frame->size - mfield_size) - 1)) ?
1377 (frame->size - mfield_size) - 1 : count;
1378 cpy_ptr++;
1379 dsize += 1;
1380 audio->reserved = 0;
1381 } else
1382 xfer = (count > (frame->size - mfield_size)) ?
1383 (frame->size - mfield_size) : count;
1384
1385 if (copy_from_user(cpy_ptr, buf, xfer)) {
1386 rc = -EFAULT;
1387 break;
1388 }
1389
1390 dsize += xfer;
1391 if (dsize & 1) {
1392 audio->rsv_byte = ((char *) frame->data)[dsize - 1];
1393 MM_DBG("odd length buf reserve last byte %x\n",
1394 audio->rsv_byte);
1395 audio->reserved = 1;
1396 dsize--;
1397 }
1398 count -= xfer;
1399 buf += xfer;
1400
1401 if (dsize > 0) {
1402 audio->out_head ^= 1;
1403 frame->used = dsize;
1404 audplay_send_data(audio, 0);
1405 }
1406 }
1407 if (eos_condition == AUDWMA_EOS_SET)
1408 rc = audwma_process_eos(audio, start, mfield_size);
1409 mutex_unlock(&audio->write_lock);
1410 if (!rc) {
1411 if (buf > start)
1412 return buf - start;
1413 }
1414 return rc;
1415}
1416
1417static int audio_release(struct inode *inode, struct file *file)
1418{
1419 struct audio *audio = file->private_data;
1420
1421 MM_INFO("audio instance 0x%08x freeing\n", (int)audio);
1422 mutex_lock(&audio->lock);
1423 audio_disable(audio);
1424 if (audio->rmt_resource_released == 0)
1425 rmt_put_resource(audio);
1426 audio_flush(audio);
1427 audio_flush_pcm_buf(audio);
1428 msm_adsp_put(audio->audplay);
1429 audpp_adec_free(audio->dec_id);
1430#ifdef CONFIG_HAS_EARLYSUSPEND
1431 unregister_early_suspend(&audio->suspend_ctl.node);
1432#endif
1433 audio->event_abort = 1;
1434 wake_up(&audio->event_wait);
1435 audwma_reset_event_queue(audio);
Laura Abbott35111d32012-04-27 18:41:48 -07001436 iounmap(audio->map_v_write);
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301437 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001438 if (audio->read_data) {
Laura Abbott35111d32012-04-27 18:41:48 -07001439 iounmap(audio->map_v_read);
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301440 free_contiguous_memory_by_paddr(audio->read_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001441 }
1442 mutex_unlock(&audio->lock);
1443#ifdef CONFIG_DEBUG_FS
1444 if (audio->dentry)
1445 debugfs_remove(audio->dentry);
1446#endif
1447 kfree(audio);
1448 return 0;
1449}
1450
1451#ifdef CONFIG_HAS_EARLYSUSPEND
1452static void audwma_post_event(struct audio *audio, int type,
1453 union msm_audio_event_payload payload)
1454{
1455 struct audwma_event *e_node = NULL;
1456 unsigned long flags;
1457
1458 spin_lock_irqsave(&audio->event_queue_lock, flags);
1459
1460 if (!list_empty(&audio->free_event_queue)) {
1461 e_node = list_first_entry(&audio->free_event_queue,
1462 struct audwma_event, list);
1463 list_del(&e_node->list);
1464 } else {
1465 e_node = kmalloc(sizeof(struct audwma_event), GFP_ATOMIC);
1466 if (!e_node) {
1467 MM_ERR("No mem to post event %d\n", type);
1468 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
1469 return;
1470 }
1471 }
1472
1473 e_node->event_type = type;
1474 e_node->payload = payload;
1475
1476 list_add_tail(&e_node->list, &audio->event_queue);
1477 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
1478 wake_up(&audio->event_wait);
1479}
1480
1481static void audwma_suspend(struct early_suspend *h)
1482{
1483 struct audwma_suspend_ctl *ctl =
1484 container_of(h, struct audwma_suspend_ctl, node);
1485 union msm_audio_event_payload payload;
1486
1487 MM_DBG("\n"); /* Macro prints the file name and function */
1488 audwma_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload);
1489}
1490
1491static void audwma_resume(struct early_suspend *h)
1492{
1493 struct audwma_suspend_ctl *ctl =
1494 container_of(h, struct audwma_suspend_ctl, node);
1495 union msm_audio_event_payload payload;
1496
1497 MM_DBG("\n"); /* Macro prints the file name and function */
1498 audwma_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload);
1499}
1500#endif
1501
1502#ifdef CONFIG_DEBUG_FS
1503static ssize_t audwma_debug_open(struct inode *inode, struct file *file)
1504{
1505 file->private_data = inode->i_private;
1506 return 0;
1507}
1508
1509static ssize_t audwma_debug_read(struct file *file, char __user *buf,
1510 size_t count, loff_t *ppos)
1511{
1512 const int debug_bufmax = 4096;
1513 static char buffer[4096];
1514 int n = 0, i;
1515 struct audio *audio = file->private_data;
1516
1517 mutex_lock(&audio->lock);
1518 n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened);
1519 n += scnprintf(buffer + n, debug_bufmax - n,
1520 "enabled %d\n", audio->enabled);
1521 n += scnprintf(buffer + n, debug_bufmax - n,
1522 "stopped %d\n", audio->stopped);
1523 n += scnprintf(buffer + n, debug_bufmax - n,
1524 "pcm_feedback %d\n", audio->pcm_feedback);
1525 n += scnprintf(buffer + n, debug_bufmax - n,
1526 "out_buf_sz %d\n", audio->out[0].size);
1527 n += scnprintf(buffer + n, debug_bufmax - n,
1528 "pcm_buf_count %d \n", audio->pcm_buf_count);
1529 n += scnprintf(buffer + n, debug_bufmax - n,
1530 "pcm_buf_sz %d \n", audio->in[0].size);
1531 n += scnprintf(buffer + n, debug_bufmax - n,
1532 "volume %x \n", audio->vol_pan.volume);
1533 n += scnprintf(buffer + n, debug_bufmax - n,
1534 "sample rate %d \n", audio->out_sample_rate);
1535 n += scnprintf(buffer + n, debug_bufmax - n,
1536 "channel mode %d \n", audio->out_channel_mode);
1537 mutex_unlock(&audio->lock);
1538 /* Following variables are only useful for debugging when
1539 * when playback halts unexpectedly. Thus, no mutual exclusion
1540 * enforced
1541 */
1542 n += scnprintf(buffer + n, debug_bufmax - n,
1543 "wflush %d\n", audio->wflush);
1544 n += scnprintf(buffer + n, debug_bufmax - n,
1545 "rflush %d\n", audio->rflush);
1546 n += scnprintf(buffer + n, debug_bufmax - n,
1547 "running %d \n", audio->running);
1548 n += scnprintf(buffer + n, debug_bufmax - n,
1549 "dec state %d \n", audio->dec_state);
1550 n += scnprintf(buffer + n, debug_bufmax - n,
1551 "out_needed %d \n", audio->out_needed);
1552 n += scnprintf(buffer + n, debug_bufmax - n,
1553 "out_head %d \n", audio->out_head);
1554 n += scnprintf(buffer + n, debug_bufmax - n,
1555 "out_tail %d \n", audio->out_tail);
1556 n += scnprintf(buffer + n, debug_bufmax - n,
1557 "out[0].used %d \n", audio->out[0].used);
1558 n += scnprintf(buffer + n, debug_bufmax - n,
1559 "out[1].used %d \n", audio->out[1].used);
1560 n += scnprintf(buffer + n, debug_bufmax - n,
1561 "buffer_refresh %d \n", audio->buf_refresh);
1562 n += scnprintf(buffer + n, debug_bufmax - n,
1563 "read_next %d \n", audio->read_next);
1564 n += scnprintf(buffer + n, debug_bufmax - n,
1565 "fill_next %d \n", audio->fill_next);
1566 for (i = 0; i < audio->pcm_buf_count; i++)
1567 n += scnprintf(buffer + n, debug_bufmax - n,
1568 "in[%d].size %d \n", i, audio->in[i].used);
1569 buffer[n] = 0;
1570 return simple_read_from_buffer(buf, count, ppos, buffer, n);
1571}
1572
1573static const struct file_operations audwma_debug_fops = {
1574 .read = audwma_debug_read,
1575 .open = audwma_debug_open,
1576};
1577#endif
1578
1579static int audio_open(struct inode *inode, struct file *file)
1580{
1581 struct audio *audio = NULL;
1582 int rc, dec_attrb, decid, i;
1583 unsigned pmem_sz = DMASZ_MAX;
1584 struct audwma_event *e_node = NULL;
1585#ifdef CONFIG_DEBUG_FS
1586 /* 4 bytes represents decoder number, 1 byte for terminate string */
1587 char name[sizeof "msm_wma_" + 5];
1588#endif
1589
1590 /* Allocate Mem for audio instance */
1591 audio = kzalloc(sizeof(struct audio), GFP_KERNEL);
1592 if (!audio) {
1593 MM_ERR("no memory to allocate audio instance \n");
1594 rc = -ENOMEM;
1595 goto done;
1596 }
1597 MM_INFO("audio instance 0x%08x created\n", (int)audio);
1598
1599 /* Allocate the decoder */
1600 dec_attrb = AUDDEC_DEC_WMA;
1601 if ((file->f_mode & FMODE_WRITE) &&
1602 (file->f_mode & FMODE_READ)) {
1603 dec_attrb |= MSM_AUD_MODE_NONTUNNEL;
1604 audio->pcm_feedback = NON_TUNNEL_MODE_PLAYBACK;
1605 } else if ((file->f_mode & FMODE_WRITE) &&
1606 !(file->f_mode & FMODE_READ)) {
1607 dec_attrb |= MSM_AUD_MODE_TUNNEL;
1608 audio->pcm_feedback = TUNNEL_MODE_PLAYBACK;
1609 } else {
1610 kfree(audio);
1611 rc = -EACCES;
1612 goto done;
1613 }
1614
1615 decid = audpp_adec_alloc(dec_attrb, &audio->module_name,
1616 &audio->queue_id);
1617
1618 if (decid < 0) {
1619 MM_ERR("No free decoder available, freeing instance 0x%08x\n",
1620 (int)audio);
1621 rc = -ENODEV;
1622 kfree(audio);
1623 goto done;
1624 }
1625 audio->dec_id = decid & MSM_AUD_DECODER_MASK;
1626
1627 while (pmem_sz >= DMASZ_MIN) {
1628 MM_DBG("pmemsz = %d\n", pmem_sz);
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301629 audio->phys = allocate_contiguous_ebi_nomap(pmem_sz, SZ_4K);
1630 if (audio->phys) {
Laura Abbott35111d32012-04-27 18:41:48 -07001631 audio->map_v_write = ioremap(audio->phys, pmem_sz);
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301632 if (IS_ERR(audio->map_v_write)) {
1633 MM_ERR("could not map write buffers, \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001634 freeing instance 0x%08x\n",
1635 (int)audio);
1636 rc = -ENOMEM;
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301637 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001638 audpp_adec_free(audio->dec_id);
1639 kfree(audio);
1640 goto done;
1641 }
Laura Abbott35111d32012-04-27 18:41:48 -07001642 audio->data = audio->map_v_write;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001643 MM_DBG("write buf: phy addr 0x%08x kernel addr \
1644 0x%08x\n", audio->phys, (int)audio->data);
1645 break;
1646 } else if (pmem_sz == DMASZ_MIN) {
1647 MM_ERR("could not allocate write buffers, freeing \
1648 instance 0x%08x\n", (int)audio);
1649 rc = -ENOMEM;
1650 audpp_adec_free(audio->dec_id);
1651 kfree(audio);
1652 goto done;
1653 } else
1654 pmem_sz >>= 1;
1655 }
1656 audio->out_dma_sz = pmem_sz;
1657
1658 if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK) {
1659 rc = audmgr_open(&audio->audmgr);
1660 if (rc) {
1661 MM_ERR("audmgr open failed, freeing instance \
1662 0x%08x\n", (int)audio);
1663 goto err;
1664 }
1665 }
1666
1667 rc = msm_adsp_get(audio->module_name, &audio->audplay,
1668 &audplay_adsp_ops_wma, audio);
1669 if (rc) {
1670 MM_ERR("failed to get %s module, freeing instance 0x%08x\n",
1671 audio->module_name, (int)audio);
1672 if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
1673 audmgr_close(&audio->audmgr);
1674 goto err;
1675 }
1676
1677 rc = rmt_get_resource(audio);
1678 if (rc) {
1679 MM_ERR("ADSP resources are not available for WMA session \
1680 0x%08x on decoder: %d\n", (int)audio, audio->dec_id);
1681 if (audio->pcm_feedback == TUNNEL_MODE_PLAYBACK)
1682 audmgr_close(&audio->audmgr);
1683 msm_adsp_put(audio->audplay);
1684 goto err;
1685 }
1686
1687 mutex_init(&audio->lock);
1688 mutex_init(&audio->write_lock);
1689 mutex_init(&audio->read_lock);
1690 mutex_init(&audio->get_event_lock);
1691 spin_lock_init(&audio->dsp_lock);
1692 init_waitqueue_head(&audio->write_wait);
1693 init_waitqueue_head(&audio->read_wait);
1694 INIT_LIST_HEAD(&audio->free_event_queue);
1695 INIT_LIST_HEAD(&audio->event_queue);
1696 init_waitqueue_head(&audio->wait);
1697 init_waitqueue_head(&audio->event_wait);
1698 spin_lock_init(&audio->event_queue_lock);
1699
1700 audio->out[0].data = audio->data + 0;
1701 audio->out[0].addr = audio->phys + 0;
1702 audio->out[0].size = audio->out_dma_sz >> 1;
1703
1704 audio->out[1].data = audio->data + audio->out[0].size;
1705 audio->out[1].addr = audio->phys + audio->out[0].size;
1706 audio->out[1].size = audio->out[0].size;
1707
1708 audio->wma_config.armdatareqthr = 1262;
1709 audio->wma_config.channelsdecoded = 2;
1710 audio->wma_config.wmabytespersec = 6003;
1711 audio->wma_config.wmasamplingfreq = 44100;
1712 audio->wma_config.wmaencoderopts = 31;
1713
1714 audio->out_sample_rate = 44100;
1715 audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
1716
1717 audio->vol_pan.volume = 0x2000;
1718
1719 audio_flush(audio);
1720
1721 file->private_data = audio;
1722 audio->opened = 1;
1723#ifdef CONFIG_DEBUG_FS
1724 snprintf(name, sizeof name, "msm_wma_%04x", audio->dec_id);
1725 audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
1726 NULL, (void *) audio,
1727 &audwma_debug_fops);
1728
1729 if (IS_ERR(audio->dentry))
1730 MM_DBG("debugfs_create_file failed\n");
1731#endif
1732#ifdef CONFIG_HAS_EARLYSUSPEND
1733 audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
1734 audio->suspend_ctl.node.resume = audwma_resume;
1735 audio->suspend_ctl.node.suspend = audwma_suspend;
1736 audio->suspend_ctl.audio = audio;
1737 register_early_suspend(&audio->suspend_ctl.node);
1738#endif
1739 for (i = 0; i < AUDWMA_EVENT_NUM; i++) {
1740 e_node = kmalloc(sizeof(struct audwma_event), GFP_KERNEL);
1741 if (e_node)
1742 list_add_tail(&e_node->list, &audio->free_event_queue);
1743 else {
1744 MM_ERR("event pkt alloc failed\n");
1745 break;
1746 }
1747 }
1748done:
1749 return rc;
1750err:
Laura Abbott35111d32012-04-27 18:41:48 -07001751 iounmap(audio->map_v_write);
Santosh Mardi0be3b8e2011-07-06 10:00:21 +05301752 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001753 audpp_adec_free(audio->dec_id);
1754 kfree(audio);
1755 return rc;
1756}
1757
1758static const struct file_operations audio_wma_fops = {
1759 .owner = THIS_MODULE,
1760 .open = audio_open,
1761 .release = audio_release,
1762 .read = audio_read,
1763 .write = audio_write,
1764 .unlocked_ioctl = audio_ioctl,
1765 .fsync = audio_fsync,
1766};
1767
1768struct miscdevice audio_wma_misc = {
1769 .minor = MISC_DYNAMIC_MINOR,
1770 .name = "msm_wma",
1771 .fops = &audio_wma_fops,
1772};
1773
1774static int __init audio_init(void)
1775{
1776 return misc_register(&audio_wma_misc);
1777}
1778
1779device_initcall(audio_init);