blob: 66d0a9e14137e5b4cd13f22a5828b49bc47dfd0d [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* amrwb audio decoder device
2 *
Duy Truong790f06d2013-02-13 16:38:12 -08003 * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004 *
5 * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5v2/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 Mardifdc227a2011-07-11 17:20:34 +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>
Santosh Mardifdc227a2011-07-11 17:20:34 +053041#include <linux/memory_alloc.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070042#include <linux/msm_audio.h>
43#include <linux/slab.h>
Santosh Mardifdc227a2011-07-11 17:20:34 +053044
45#include <mach/msm_adsp.h>
46#include <mach/iommu.h>
47#include <mach/iommu_domains.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070048#include <mach/qdsp5v2/qdsp5audppmsg.h>
49#include <mach/qdsp5v2/qdsp5audplaycmdi.h>
50#include <mach/qdsp5v2/qdsp5audplaymsg.h>
51#include <mach/qdsp5v2/audio_dev_ctl.h>
52#include <mach/qdsp5v2/audpp.h>
53#include <mach/debug_mm.h>
Santosh Mardifdc227a2011-07-11 17:20:34 +053054#include <mach/msm_memtypes.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070055
56#define BUFSZ 4110 /* Hold minimum 700ms voice data and 14 bytes of meta in*/
57#define DMASZ (BUFSZ * 2)
58
59#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF
60#define AUDDEC_DEC_AMRWB 11
61
62#define PCM_BUFSZ_MIN 8216 /* 100ms worth of data and 24 bytes of meta out*/
63#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most
64 but support 2 buffers currently */
65#define ROUTING_MODE_FTRT 1
66#define ROUTING_MODE_RT 2
67/* Decoder status received from AUDPPTASK */
68#define AUDPP_DEC_STATUS_SLEEP 0
69#define AUDPP_DEC_STATUS_INIT 1
70#define AUDPP_DEC_STATUS_CFG 2
71#define AUDPP_DEC_STATUS_PLAY 3
72
73#define AUDAMRWB_METAFIELD_MASK 0xFFFF0000
74#define AUDAMRWB_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */
75#define AUDAMRWB_EOS_FLG_MASK 0x01
76#define AUDAMRWB_EOS_NONE 0x0 /* No EOS detected */
77#define AUDAMRWB_EOS_SET 0x1 /* EOS set in meta field */
78
79#define AUDAMRWB_EVENT_NUM 10 /* Default number of pre-allocated event pkts */
80
81struct buffer {
82 void *data;
83 unsigned size;
84 unsigned used; /* Input usage actual DSP produced PCM size */
85 unsigned addr;
86 unsigned short mfield_sz; /*only useful for data has meta field */
87};
88
89#ifdef CONFIG_HAS_EARLYSUSPEND
90struct audamrwb_suspend_ctl {
91 struct early_suspend node;
92 struct audio *audio;
93};
94#endif
95
96struct audamrwb_event{
97 struct list_head list;
98 int event_type;
99 union msm_audio_event_payload payload;
100};
101
102struct audio {
103 struct buffer out[2];
104
105 spinlock_t dsp_lock;
106
107 uint8_t out_head;
108 uint8_t out_tail;
109 uint8_t out_needed; /* number of buffers the dsp is waiting for */
110
111 atomic_t out_bytes;
112
113 struct mutex lock;
114 struct mutex write_lock;
115 wait_queue_head_t write_wait;
116
117 /* Host PCM section */
118 struct buffer in[PCM_BUF_MAX_COUNT];
119 struct mutex read_lock;
120 wait_queue_head_t read_wait; /* Wait queue for read */
121 char *read_data; /* pointer to reader buffer */
122 int32_t read_phys; /* physical address of reader buffer */
123 uint8_t read_next; /* index to input buffers to be read next */
124 uint8_t fill_next; /* index to buffer that DSP should be filling */
125 uint8_t pcm_buf_count; /* number of pcm buffer allocated */
126 /* ---- End of Host PCM section */
127
128 struct msm_adsp_module *audplay;
129
130 /* configuration to use on next enable */
131 uint32_t out_sample_rate;
132 uint32_t out_channel_mode;
133
134 /* data allocated for various buffers */
135 char *data;
136 int32_t phys; /* physical address of write buffer */
137
Laura Abbott61399692012-04-30 14:25:46 -0700138 void *map_v_read;
139 void *map_v_write;
Santosh Mardifdc227a2011-07-11 17:20:34 +0530140
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700141 int mfield; /* meta field embedded in data */
142 int rflush; /* Read flush */
143 int wflush; /* Write flush */
144 int opened;
145 int enabled;
146 int running;
147 int stopped; /* set when stopped, cleared on flush */
148 int pcm_feedback;
149 int buf_refresh;
150 int teos; /* valid only if tunnel mode & no data left for decoder */
151 enum msm_aud_decoder_state dec_state; /* Represents decoder state */
152 int reserved; /* A byte is being reserved */
153 char rsv_byte; /* Handle odd length user data */
154
155 const char *module_name;
156 unsigned queue_id;
157 uint16_t dec_id;
158 uint32_t read_ptr_offset;
159 int16_t source;
160
161#ifdef CONFIG_HAS_EARLYSUSPEND
162 struct audamrwb_suspend_ctl suspend_ctl;
163#endif
164
165#ifdef CONFIG_DEBUG_FS
166 struct dentry *dentry;
167#endif
168
169 wait_queue_head_t wait;
170 struct list_head free_event_queue;
171 struct list_head event_queue;
172 wait_queue_head_t event_wait;
173 spinlock_t event_queue_lock;
174 struct mutex get_event_lock;
175 int event_abort;
176 /* AV sync Info */
177 int avsync_flag; /* Flag to indicate feedback from DSP */
178 wait_queue_head_t avsync_wait;/* Wait queue for AV Sync Message */
179 /* flags, 48 bits sample/bytes counter per channel */
180 uint16_t avsync[AUDPP_AVSYNC_CH_COUNT * AUDPP_AVSYNC_NUM_WORDS + 1];
181
182 uint32_t device_events;
183
184 int eq_enable;
185 int eq_needs_commit;
186 struct audpp_cmd_cfg_object_params_eqalizer eq;
187 struct audpp_cmd_cfg_object_params_volume vol_pan;
188};
189
190static int auddec_dsp_config(struct audio *audio, int enable);
191static void audpp_cmd_cfg_adec_params(struct audio *audio);
192static void audpp_cmd_cfg_routing_mode(struct audio *audio);
193static void audamrwb_send_data(struct audio *audio, unsigned needed);
194static void audamrwb_config_hostpcm(struct audio *audio);
195static void audamrwb_buffer_refresh(struct audio *audio);
196static void audamrwb_dsp_event(void *private, unsigned id, uint16_t *msg);
Vinay Vaka051db722012-01-24 19:48:32 +0530197#ifdef CONFIG_HAS_EARLYSUSPEND
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700198static void audamrwb_post_event(struct audio *audio, int type,
199 union msm_audio_event_payload payload);
Vinay Vaka051db722012-01-24 19:48:32 +0530200#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700201
202/* must be called with audio->lock held */
203static int audamrwb_enable(struct audio *audio)
204{
205
206 MM_DBG("\n"); /* Macro prints the file name and function */
207
208 if (audio->enabled)
209 return 0;
210
211 audio->dec_state = MSM_AUD_DECODER_STATE_NONE;
212 audio->out_tail = 0;
213 audio->out_needed = 0;
214
215 if (msm_adsp_enable(audio->audplay)) {
216 MM_ERR("msm_adsp_enable(audplay) failed\n");
217 return -ENODEV;
218 }
219
220 if (audpp_enable(audio->dec_id, audamrwb_dsp_event, audio)) {
221 MM_ERR("audpp_enable() failed\n");
222 msm_adsp_disable(audio->audplay);
223 return -ENODEV;
224 }
225 audio->enabled = 1;
226 return 0;
227}
228
229static void amrwb_listner(u32 evt_id, union auddev_evt_data *evt_payload,
230 void *private_data)
231{
232 struct audio *audio = (struct audio *) private_data;
233 switch (evt_id) {
234 case AUDDEV_EVT_DEV_RDY:
235 MM_DBG("AUDDEV_EVT_DEV_RDY\n");
236 audio->source |= (0x1 << evt_payload->routing_id);
237 if (audio->running == 1 && audio->enabled == 1)
238 audpp_route_stream(audio->dec_id, audio->source);
239 break;
240 case AUDDEV_EVT_DEV_RLS:
241 MM_DBG("AUDDEV_EVT_DEV_RLS\n");
242 audio->source &= ~(0x1 << evt_payload->routing_id);
243 if (audio->running == 1 && audio->enabled == 1)
244 audpp_route_stream(audio->dec_id, audio->source);
245 break;
246 case AUDDEV_EVT_STREAM_VOL_CHG:
247 audio->vol_pan.volume = evt_payload->session_vol;
248 MM_DBG("AUDDEV_EVT_STREAM_VOL_CHG, stream vol %d\n",
249 audio->vol_pan.volume);
250 if (audio->running)
251 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan,
252 POPP);
253 break;
254 default:
255 MM_ERR("ERROR:wrong event\n");
256 break;
257 }
258}
259
260/* must be called with audio->lock held */
261static int audamrwb_disable(struct audio *audio)
262{
263 int rc = 0;
264 MM_DBG("\n"); /* Macro prints the file name and function */
265 if (audio->enabled) {
266 audio->enabled = 0;
267 audio->dec_state = MSM_AUD_DECODER_STATE_NONE;
268 auddec_dsp_config(audio, 0);
269 rc = wait_event_interruptible_timeout(audio->wait,
270 audio->dec_state != MSM_AUD_DECODER_STATE_NONE,
271 msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS));
272 if (rc == 0)
273 rc = -ETIMEDOUT;
274 else if (audio->dec_state != MSM_AUD_DECODER_STATE_CLOSE)
275 rc = -EFAULT;
276 else
277 rc = 0;
278 wake_up(&audio->write_wait);
279 wake_up(&audio->read_wait);
280 msm_adsp_disable(audio->audplay);
281 audpp_disable(audio->dec_id, audio);
282 audio->out_needed = 0;
283 }
284 return rc;
285}
286
287/* ------------------- dsp --------------------- */
288static void audamrwb_update_pcm_buf_entry(struct audio *audio,
289 uint32_t *payload)
290{
291 uint8_t index;
292 unsigned long flags;
293
294 if (audio->rflush)
295 return;
296
297 spin_lock_irqsave(&audio->dsp_lock, flags);
298 for (index = 0; index < payload[1]; index++) {
299 if (audio->in[audio->fill_next].addr ==
300 payload[2 + index * 2]) {
301 MM_DBG("audamrwb_update_pcm_buf_entry: \
302 in[%d] ready\n", audio->fill_next);
303 audio->in[audio->fill_next].used =
304 payload[3 + index * 2];
305 if ((++audio->fill_next) == audio->pcm_buf_count)
306 audio->fill_next = 0;
307
308 } else {
309 MM_ERR("expected=%x ret=%x\n",
310 audio->in[audio->fill_next].addr,
311 payload[1 + index * 2]);
312 break;
313 }
314 }
315 if (audio->in[audio->fill_next].used == 0) {
316 audamrwb_buffer_refresh(audio);
317 } else {
318 MM_DBG("audamrwb_update_pcm_buf_entry: \
319 read cannot keep up\n");
320 audio->buf_refresh = 1;
321 }
322 wake_up(&audio->read_wait);
323 spin_unlock_irqrestore(&audio->dsp_lock, flags);
324}
325
326static void audplay_dsp_event(void *data, unsigned id, size_t len,
327 void (*getevent) (void *ptr, size_t len))
328{
329 struct audio *audio = data;
330 uint32_t msg[28];
331 getevent(msg, sizeof(msg));
332
333 MM_DBG("audplay_dsp_event: msg_id=%x\n", id);
334
335 switch (id) {
336 case AUDPLAY_MSG_DEC_NEEDS_DATA:
337 audamrwb_send_data(audio, 1);
338 break;
339
340 case AUDPLAY_MSG_BUFFER_UPDATE:
341 audamrwb_update_pcm_buf_entry(audio, msg);
342 break;
343
344 case ADSP_MESSAGE_ID:
345 MM_DBG("Received ADSP event:module audplaytask\n");
346 break;
347
348 default:
349 MM_DBG("unexpected message from decoder\n");
350 }
351}
352
353static void audamrwb_dsp_event(void *private, unsigned id, uint16_t *msg)
354{
355 struct audio *audio = private;
356
357 switch (id) {
358 case AUDPP_MSG_STATUS_MSG:{
359 unsigned status = msg[1];
360
361 switch (status) {
362 case AUDPP_DEC_STATUS_SLEEP: {
363 uint16_t reason = msg[2];
364 MM_DBG("decoder status:sleep reason=0x%04x\n",
365 reason);
366 if ((reason == AUDPP_MSG_REASON_MEM)
367 || (reason ==
368 AUDPP_MSG_REASON_NODECODER)) {
369 audio->dec_state =
370 MSM_AUD_DECODER_STATE_FAILURE;
371 wake_up(&audio->wait);
372 } else if (reason == AUDPP_MSG_REASON_NONE) {
373 /* decoder is in disable state */
374 audio->dec_state =
375 MSM_AUD_DECODER_STATE_CLOSE;
376 wake_up(&audio->wait);
377 }
378 break;
379 }
380 case AUDPP_DEC_STATUS_INIT:
381 MM_DBG("decoder status: init\n");
382 if (audio->pcm_feedback)
383 audpp_cmd_cfg_routing_mode(audio);
384 else
385 audpp_cmd_cfg_adec_params(audio);
386 break;
387
388 case AUDPP_DEC_STATUS_CFG:
389 MM_DBG("decoder status: cfg\n");
390 break;
391 case AUDPP_DEC_STATUS_PLAY:
392 MM_DBG("decoder status: play\n");
393 /* send mixer command */
394 audpp_route_stream(audio->dec_id,
395 audio->source);
396 if (audio->pcm_feedback) {
397 audamrwb_config_hostpcm(audio);
398 audamrwb_buffer_refresh(audio);
399 }
400 audio->dec_state =
401 MSM_AUD_DECODER_STATE_SUCCESS;
402 wake_up(&audio->wait);
403 break;
404 default:
405 MM_DBG("unknown decoder status\n");
406 break;
407 }
408 break;
409 }
410 case AUDPP_MSG_CFG_MSG:
411 if (msg[0] == AUDPP_MSG_ENA_ENA) {
412 MM_DBG("CFG_MSG ENABLE\n");
413 auddec_dsp_config(audio, 1);
414 audio->out_needed = 0;
415 audio->running = 1;
416 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan,
417 POPP);
418 audpp_dsp_set_eq(audio->dec_id, audio->eq_enable,
419 &audio->eq, POPP);
420 } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
421 MM_DBG("CFG_MSG DISABLE\n");
422 audio->running = 0;
423 } else {
424 MM_DBG("CFG_MSG %d?\n", msg[0]);
425 }
426 break;
427 case AUDPP_MSG_ROUTING_ACK:
428 MM_DBG("ROUTING_ACK mode=%d\n", msg[1]);
429 audpp_cmd_cfg_adec_params(audio);
430 break;
431 case AUDPP_MSG_FLUSH_ACK:
432 MM_DBG("FLUSH_ACK\n");
433 audio->wflush = 0;
434 audio->rflush = 0;
435 wake_up(&audio->write_wait);
436 if (audio->pcm_feedback)
437 audamrwb_buffer_refresh(audio);
438 break;
439 case AUDPP_MSG_PCMDMAMISSED:
440 MM_DBG("PCMDMAMISSED\n");
441 audio->teos = 1;
442 wake_up(&audio->write_wait);
443 break;
444
445 case AUDPP_MSG_AVSYNC_MSG:
446 MM_DBG("AUDPP_MSG_AVSYNC_MSG\n");
447 memcpy(&audio->avsync[0], msg, sizeof(audio->avsync));
448 audio->avsync_flag = 1;
449 wake_up(&audio->avsync_wait);
450 break;
451
452 default:
453 MM_DBG("UNKNOWN (%d)\n", id);
454 }
455
456}
457
458struct msm_adsp_ops audplay_adsp_ops_amrwb = {
459 .event = audplay_dsp_event,
460};
461
462#define audplay_send_queue0(audio, cmd, len) \
463 msm_adsp_write(audio->audplay, audio->queue_id, \
464 cmd, len)
465
466static int auddec_dsp_config(struct audio *audio, int enable)
467{
468 struct audpp_cmd_cfg_dec_type cfg_dec_cmd;
469
470 memset(&cfg_dec_cmd, 0, sizeof(cfg_dec_cmd));
471
472 cfg_dec_cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
473 if (enable)
474 cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
475 AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRWB;
476 else
477 cfg_dec_cmd.dec_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
478 AUDPP_CMD_DIS_DEC_V;
479 cfg_dec_cmd.dm_mode = 0x0;
480 cfg_dec_cmd.stream_id = audio->dec_id;
481 return audpp_send_queue1(&cfg_dec_cmd, sizeof(cfg_dec_cmd));
482}
483
484static void audpp_cmd_cfg_adec_params(struct audio *audio)
485{
486 struct audpp_cmd_cfg_adec_params_amrwb cmd;
487
488 memset(&cmd, 0, sizeof(cmd));
489 cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
490 cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AMRWB_LEN;
491 cmd.common.dec_id = audio->dec_id;
492 cmd.common.input_sampling_frequency = audio->out_sample_rate;
493 cmd.stereo_cfg = audio->out_channel_mode;
494 audpp_send_queue2(&cmd, sizeof(cmd));
495}
496
497static void audpp_cmd_cfg_routing_mode(struct audio *audio)
498{
499 struct audpp_cmd_routing_mode cmd;
500 MM_DBG("\n"); /* Macro prints the file name and function */
501 memset(&cmd, 0, sizeof(cmd));
502 cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
503 cmd.object_number = audio->dec_id;
504 if (audio->pcm_feedback)
505 cmd.routing_mode = ROUTING_MODE_FTRT;
506 else
507 cmd.routing_mode = ROUTING_MODE_RT;
508
509 audpp_send_queue1(&cmd, sizeof(cmd));
510}
511
512static int audplay_dsp_send_data_avail(struct audio *audio,
513 unsigned idx, unsigned len)
514{
515 struct audplay_cmd_bitstream_data_avail_nt2 cmd;
516
517 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL_NT2;
518 if (audio->mfield)
519 cmd.decoder_id = AUDAMRWB_METAFIELD_MASK |
520 (audio->out[idx].mfield_sz >> 1);
521 else
522 cmd.decoder_id = audio->dec_id;
523 cmd.buf_ptr = audio->out[idx].addr;
524 cmd.buf_size = len / 2;
525 cmd.partition_number = 0;
526 return audplay_send_queue0(audio, &cmd, sizeof(cmd));
527}
528
529static void audamrwb_buffer_refresh(struct audio *audio)
530{
531 struct audplay_cmd_buffer_refresh refresh_cmd;
532
533 refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
534 refresh_cmd.num_buffers = 1;
535 refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
536 refresh_cmd.buf0_length = audio->in[audio->fill_next].size;
537 refresh_cmd.buf_read_count = 0;
538 MM_DBG("buf0_addr=%x buf0_len=%d\n", refresh_cmd.buf0_address,
539 refresh_cmd.buf0_length);
540 (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
541}
542
543static void audamrwb_config_hostpcm(struct audio *audio)
544{
545 struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
546
547 MM_DBG("\n"); /* Macro prints the file name and function */
548 cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
549 cfg_cmd.max_buffers = audio->pcm_buf_count;
550 cfg_cmd.byte_swap = 0;
551 cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
552 cfg_cmd.feedback_frequency = 1;
553 cfg_cmd.partition_number = 0;
554 (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
555
556}
557
558static void audamrwb_send_data(struct audio *audio, unsigned needed)
559{
560 struct buffer *frame;
561 unsigned long flags;
562
563 spin_lock_irqsave(&audio->dsp_lock, flags);
564 if (!audio->running)
565 goto done;
566
567 if (needed && !audio->wflush) {
568 /* We were called from the callback because the DSP
569 * requested more data. Note that the DSP does want
570 * more data, and if a buffer was in-flight, mark it
571 * as available (since the DSP must now be done with
572 * it).
573 */
574 audio->out_needed = 1;
575 frame = audio->out + audio->out_tail;
576 if (frame->used == 0xffffffff) {
577 frame->used = 0;
578 audio->out_tail ^= 1;
579 wake_up(&audio->write_wait);
580 }
581 }
582
583 if (audio->out_needed) {
584 /* If the DSP currently wants data and we have a
585 * buffer available, we will send it and reset
586 * the needed flag. We'll mark the buffer as in-flight
587 * so that it won't be recycled until the next buffer
588 * is requested
589 */
590
591 frame = audio->out + audio->out_tail;
592 if (frame->used) {
593 BUG_ON(frame->used == 0xffffffff);
594 MM_DBG("frame %d busy\n", audio->out_tail);
595 audplay_dsp_send_data_avail(audio, audio->out_tail,
596 frame->used);
597 frame->used = 0xffffffff;
598 audio->out_needed = 0;
599 }
600 }
601 done:
602 spin_unlock_irqrestore(&audio->dsp_lock, flags);
603}
604
605/* ------------------- device --------------------- */
606
607static void audamrwb_flush(struct audio *audio)
608{
609 audio->out[0].used = 0;
610 audio->out[1].used = 0;
611 audio->out_head = 0;
612 audio->out_tail = 0;
613 audio->reserved = 0;
614 audio->out_needed = 0;
615 atomic_set(&audio->out_bytes, 0);
616}
617
618static void audamrwb_flush_pcm_buf(struct audio *audio)
619{
620 uint8_t index;
621
622 for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
623 audio->in[index].used = 0;
624
625 audio->buf_refresh = 0;
626 audio->read_next = 0;
627 audio->fill_next = 0;
628}
629
630static void audamrwb_ioport_reset(struct audio *audio)
631{
632 /* Make sure read/write thread are free from
633 * sleep and knowing that system is not able
634 * to process io request at the moment
635 */
636 wake_up(&audio->write_wait);
637 mutex_lock(&audio->write_lock);
638 audamrwb_flush(audio);
639 mutex_unlock(&audio->write_lock);
640 wake_up(&audio->read_wait);
641 mutex_lock(&audio->read_lock);
642 audamrwb_flush_pcm_buf(audio);
643 mutex_unlock(&audio->read_lock);
644 audio->avsync_flag = 1;
645 wake_up(&audio->avsync_wait);
646}
647
648static int audamrwb_events_pending(struct audio *audio)
649{
650 unsigned long flags;
651 int empty;
652
653 spin_lock_irqsave(&audio->event_queue_lock, flags);
654 empty = !list_empty(&audio->event_queue);
655 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
656 return empty || audio->event_abort;
657}
658
659static void audamrwb_reset_event_queue(struct audio *audio)
660{
661 unsigned long flags;
662 struct audamrwb_event *drv_evt;
663 struct list_head *ptr, *next;
664
665 spin_lock_irqsave(&audio->event_queue_lock, flags);
666 list_for_each_safe(ptr, next, &audio->event_queue) {
667 drv_evt = list_first_entry(&audio->event_queue,
668 struct audamrwb_event, list);
669 list_del(&drv_evt->list);
670 kfree(drv_evt);
671 }
672 list_for_each_safe(ptr, next, &audio->free_event_queue) {
673 drv_evt = list_first_entry(&audio->free_event_queue,
674 struct audamrwb_event, list);
675 list_del(&drv_evt->list);
676 kfree(drv_evt);
677 }
678 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
679
680 return;
681}
682
683static long audamrwb_process_event_req(struct audio *audio, void __user *arg)
684{
685 long rc;
686 struct msm_audio_event usr_evt;
687 struct audamrwb_event *drv_evt = NULL;
688 int timeout;
689 unsigned long flags;
690
691 if (copy_from_user(&usr_evt, arg, sizeof(struct msm_audio_event)))
692 return -EFAULT;
693
694 timeout = (int) usr_evt.timeout_ms;
695
696 if (timeout > 0) {
697 rc = wait_event_interruptible_timeout(
698 audio->event_wait, audamrwb_events_pending(audio),
699 msecs_to_jiffies(timeout));
700 if (rc == 0)
701 return -ETIMEDOUT;
702 } else {
703 rc = wait_event_interruptible(
704 audio->event_wait, audamrwb_events_pending(audio));
705 }
706
707 if (rc < 0)
708 return rc;
709
710 if (audio->event_abort) {
711 audio->event_abort = 0;
712 return -ENODEV;
713 }
714
715 rc = 0;
716
717 spin_lock_irqsave(&audio->event_queue_lock, flags);
718 if (!list_empty(&audio->event_queue)) {
719 drv_evt = list_first_entry(&audio->event_queue,
720 struct audamrwb_event, list);
721 list_del(&drv_evt->list);
722 }
723
724 if (drv_evt) {
725 usr_evt.event_type = drv_evt->event_type;
726 usr_evt.event_payload = drv_evt->payload;
727 list_add_tail(&drv_evt->list, &audio->free_event_queue);
728 } else
729 rc = -1;
730 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
731
732 if (!rc && copy_to_user(arg, &usr_evt, sizeof(usr_evt)))
733 rc = -EFAULT;
734
735 return rc;
736}
737
738static int audio_enable_eq(struct audio *audio, int enable)
739{
740 if (audio->eq_enable == enable && !audio->eq_needs_commit)
741 return 0;
742
743 audio->eq_enable = enable;
744
745 if (audio->running) {
746 audpp_dsp_set_eq(audio->dec_id, enable, &audio->eq, POPP);
747 audio->eq_needs_commit = 0;
748 }
749 return 0;
750}
751
752static int audio_get_avsync_data(struct audio *audio,
753 struct msm_audio_stats *stats)
754{
755 int rc = -EINVAL;
756 unsigned long flags;
757
758 local_irq_save(flags);
759 if (audio->dec_id == audio->avsync[0] && audio->avsync_flag) {
760 /* av_sync sample count */
761 stats->sample_count = (audio->avsync[2] << 16) |
762 (audio->avsync[3]);
763
764 /* av_sync byte_count */
765 stats->byte_count = (audio->avsync[5] << 16) |
766 (audio->avsync[6]);
767
768 audio->avsync_flag = 0;
769 rc = 0;
770 }
771 local_irq_restore(flags);
772 return rc;
773
774}
775
776static long audamrwb_ioctl(struct file *file, unsigned int cmd,
777 unsigned long arg)
778{
779 struct audio *audio = file->private_data;
780 int rc = -EINVAL;
781 unsigned long flags = 0;
782 uint16_t enable_mask;
783 int enable;
784 int prev_state;
785
786 MM_DBG("cmd = %d\n", cmd);
787
788 if (cmd == AUDIO_GET_STATS) {
789 struct msm_audio_stats stats;
790
791 audio->avsync_flag = 0;
792 memset(&stats, 0, sizeof(stats));
793 if (audpp_query_avsync(audio->dec_id) < 0)
794 return rc;
795
796 rc = wait_event_interruptible_timeout(audio->avsync_wait,
797 (audio->avsync_flag == 1),
798 msecs_to_jiffies(AUDPP_AVSYNC_EVENT_TIMEOUT));
799
800 if (rc < 0)
801 return rc;
802 else if ((rc > 0) || ((rc == 0) && (audio->avsync_flag == 1))) {
803 if (audio_get_avsync_data(audio, &stats) < 0)
804 return rc;
805
806 if (copy_to_user((void *)arg, &stats, sizeof(stats)))
807 return -EFAULT;
808 return 0;
809 } else
810 return -EAGAIN;
811 }
812
813 switch (cmd) {
814 case AUDIO_ENABLE_AUDPP:
815 if (copy_from_user(&enable_mask, (void *) arg,
816 sizeof(enable_mask))) {
817 rc = -EFAULT;
818 break;
819 }
820
821 spin_lock_irqsave(&audio->dsp_lock, flags);
822 enable = (enable_mask & EQ_ENABLE) ? 1 : 0;
823 audio_enable_eq(audio, enable);
824 spin_unlock_irqrestore(&audio->dsp_lock, flags);
825 rc = 0;
826 break;
827 case AUDIO_SET_VOLUME:
828 spin_lock_irqsave(&audio->dsp_lock, flags);
829 audio->vol_pan.volume = arg;
830 if (audio->running)
831 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan,
832 POPP);
833 spin_unlock_irqrestore(&audio->dsp_lock, flags);
834 rc = 0;
835 break;
836
837 case AUDIO_SET_PAN:
838 spin_lock_irqsave(&audio->dsp_lock, flags);
839 audio->vol_pan.pan = arg;
840 if (audio->running)
841 audpp_dsp_set_vol_pan(audio->dec_id, &audio->vol_pan,
842 POPP);
843 spin_unlock_irqrestore(&audio->dsp_lock, flags);
844 rc = 0;
845 break;
846
847 case AUDIO_SET_EQ:
848 prev_state = audio->eq_enable;
849 audio->eq_enable = 0;
850 if (copy_from_user(&audio->eq.num_bands, (void *) arg,
851 sizeof(audio->eq) -
852 (AUDPP_CMD_CFG_OBJECT_PARAMS_COMMON_LEN + 2))) {
853 rc = -EFAULT;
854 break;
855 }
856 audio->eq_enable = prev_state;
857 audio->eq_needs_commit = 1;
858 rc = 0;
859 break;
860 }
861
862 if (-EINVAL != rc)
863 return rc;
864
865 if (cmd == AUDIO_GET_EVENT) {
866 MM_DBG("AUDIO_GET_EVENT\n");
867 if (mutex_trylock(&audio->get_event_lock)) {
868 rc = audamrwb_process_event_req(audio,
869 (void __user *) arg);
870 mutex_unlock(&audio->get_event_lock);
871 } else
872 rc = -EBUSY;
873 return rc;
874 }
875
876 if (cmd == AUDIO_ABORT_GET_EVENT) {
877 audio->event_abort = 1;
878 wake_up(&audio->event_wait);
879 return 0;
880 }
881
882 mutex_lock(&audio->lock);
883 switch (cmd) {
884 case AUDIO_START:
885 MM_DBG("AUDIO_START\n");
886 rc = audamrwb_enable(audio);
887 if (!rc) {
888 rc = wait_event_interruptible_timeout(audio->wait,
889 audio->dec_state != MSM_AUD_DECODER_STATE_NONE,
890 msecs_to_jiffies(MSM_AUD_DECODER_WAIT_MS));
891 MM_INFO("dec_state %d rc = %d\n", audio->dec_state, rc);
892
893 if (audio->dec_state != MSM_AUD_DECODER_STATE_SUCCESS)
894 rc = -ENODEV;
895 else
896 rc = 0;
897 }
898 break;
899 case AUDIO_STOP:
900 MM_DBG("AUDIO_STOP\n");
901 rc = audamrwb_disable(audio);
902 audio->stopped = 1;
903 audamrwb_ioport_reset(audio);
904 audio->stopped = 0;
905 break;
906 case AUDIO_FLUSH:
907 MM_DBG("AUDIO_FLUSH\n");
908 audio->rflush = 1;
909 audio->wflush = 1;
910 audamrwb_ioport_reset(audio);
911 if (audio->running) {
912 audpp_flush(audio->dec_id);
913 rc = wait_event_interruptible(audio->write_wait,
914 !audio->wflush);
915 if (rc < 0) {
916 MM_ERR("AUDIO_FLUSH interrupted\n");
917 rc = -EINTR;
918 }
919 } else {
920 audio->rflush = 0;
921 audio->wflush = 0;
922 }
923 break;
924 case AUDIO_SET_CONFIG:{
925 struct msm_audio_config config;
926 if (copy_from_user
927 (&config, (void *)arg, sizeof(config))) {
928 rc = -EFAULT;
929 break;
930 }
931 if (config.channel_count == 1)
932 config.channel_count =
933 AUDPP_CMD_PCM_INTF_MONO_V;
934 else if (config.channel_count == 2)
935 config.channel_count =
936 AUDPP_CMD_PCM_INTF_STEREO_V;
937 else
938 rc = -EINVAL;
939 audio->out_channel_mode = config.channel_count;
940 audio->out_sample_rate = config.sample_rate;
941 audio->mfield = config.meta_field;
942 rc = 0;
943 break;
944 }
945 case AUDIO_GET_CONFIG:{
946 struct msm_audio_config config;
947 config.buffer_size = BUFSZ;
948 config.buffer_count = 2;
949 config.sample_rate = audio->out_sample_rate;
950 if (audio->out_channel_mode ==
951 AUDPP_CMD_PCM_INTF_MONO_V)
952 config.channel_count = 1;
953 else
954 config.channel_count = 2;
955 config.meta_field = 0;
956 config.unused[0] = 0;
957 config.unused[1] = 0;
958 config.unused[2] = 0;
959 if (copy_to_user((void *)arg, &config,
960 sizeof(config)))
961 rc = -EFAULT;
962 else
963 rc = 0;
964
965 break;
966 }
967 case AUDIO_GET_PCM_CONFIG:{
968 struct msm_audio_pcm_config config;
969 config.pcm_feedback = 0;
970 config.buffer_count = PCM_BUF_MAX_COUNT;
971 config.buffer_size = PCM_BUFSZ_MIN;
972 if (copy_to_user((void *)arg, &config,
973 sizeof(config)))
974 rc = -EFAULT;
975 else
976 rc = 0;
977 break;
978 }
979 case AUDIO_SET_PCM_CONFIG:{
980 struct msm_audio_pcm_config config;
981 if (copy_from_user
982 (&config, (void *)arg, sizeof(config))) {
983 rc = -EFAULT;
984 break;
985 }
986 if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
987 (config.buffer_count == 1))
988 config.buffer_count = PCM_BUF_MAX_COUNT;
989
990 if (config.buffer_size < PCM_BUFSZ_MIN)
991 config.buffer_size = PCM_BUFSZ_MIN;
992
993 /* Check if pcm feedback is required */
994 if ((config.pcm_feedback) && (!audio->read_data)) {
995 MM_DBG("allocate PCM buf %d\n", config.buffer_count *
996 config.buffer_size);
Santosh Mardifdc227a2011-07-11 17:20:34 +0530997 audio->read_phys = allocate_contiguous_ebi_nomap(
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700998 config.buffer_size *
999 config.buffer_count,
Santosh Mardifdc227a2011-07-11 17:20:34 +05301000 SZ_4K);
1001 if (!audio->read_phys) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001002 rc = -ENOMEM;
1003 break;
1004 }
Laura Abbott61399692012-04-30 14:25:46 -07001005 audio->map_v_read = ioremap(
Santosh Mardifdc227a2011-07-11 17:20:34 +05301006 audio->read_phys,
1007 config.buffer_size *
Laura Abbott61399692012-04-30 14:25:46 -07001008 config.buffer_count);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301009 if (IS_ERR(audio->map_v_read)) {
1010 MM_ERR("Error could not map read"
1011 " phys address\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001012 rc = -ENOMEM;
Santosh Mardifdc227a2011-07-11 17:20:34 +05301013 free_contiguous_memory_by_paddr(
1014 audio->read_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001015 } else {
1016 uint8_t index;
1017 uint32_t offset = 0;
Laura Abbott61399692012-04-30 14:25:46 -07001018 audio->read_data = audio->map_v_read;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001019 audio->pcm_feedback = 1;
1020 audio->buf_refresh = 0;
1021 audio->pcm_buf_count =
1022 config.buffer_count;
1023 audio->read_next = 0;
1024 audio->fill_next = 0;
1025
1026 for (index = 0;
1027 index < config.buffer_count; index++) {
1028 audio->in[index].data =
1029 audio->read_data + offset;
1030 audio->in[index].addr =
1031 audio->read_phys + offset;
1032 audio->in[index].size =
1033 config.buffer_size;
1034 audio->in[index].used = 0;
1035 offset += config.buffer_size;
1036 }
1037 MM_DBG("read buf: phy addr 0x%08x \
1038 kernel addr 0x%08x\n",
1039 audio->read_phys,
1040 (int)audio->read_data);
1041 rc = 0;
1042 }
1043 } else {
1044 rc = 0;
1045 }
1046 break;
1047 }
1048 case AUDIO_GET_SESSION_ID:
1049 if (copy_to_user((void *) arg, &audio->dec_id,
1050 sizeof(unsigned short)))
1051 rc = -EFAULT;
1052 else
1053 rc = 0;
1054 break;
1055 default:
1056 rc = -EINVAL;
1057 }
1058 mutex_unlock(&audio->lock);
1059 return rc;
1060}
1061
1062/* Only useful in tunnel-mode */
Steve Mucklef132c6c2012-06-06 18:30:57 -07001063static int audamrwb_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001064{
1065 struct audio *audio = file->private_data;
1066 struct buffer *frame;
1067 int rc = 0;
1068
1069 MM_DBG("\n"); /* Macro prints the file name and function */
1070
1071 if (!audio->running || audio->pcm_feedback) {
1072 rc = -EINVAL;
1073 goto done_nolock;
1074 }
1075
1076 mutex_lock(&audio->write_lock);
1077
1078 rc = wait_event_interruptible(audio->write_wait,
1079 (!audio->out[0].used &&
1080 !audio->out[1].used &&
1081 audio->out_needed) || audio->wflush);
1082
1083 if (rc < 0)
1084 goto done;
1085 else if (audio->wflush) {
1086 rc = -EBUSY;
1087 goto done;
1088 }
1089
1090 if (audio->reserved) {
1091 MM_DBG("send reserved byte\n");
1092 frame = audio->out + audio->out_tail;
1093 ((char *) frame->data)[0] = audio->rsv_byte;
1094 ((char *) frame->data)[1] = 0;
1095 frame->used = 2;
1096 audamrwb_send_data(audio, 0);
1097
1098 rc = wait_event_interruptible(audio->write_wait,
1099 (!audio->out[0].used &&
1100 !audio->out[1].used &&
1101 audio->out_needed) || audio->wflush);
1102
1103 if (rc < 0)
1104 goto done;
1105 else if (audio->wflush) {
1106 rc = -EBUSY;
1107 goto done;
1108 }
1109 }
1110
1111 /* pcm dmamiss message is sent continously
1112 * when decoder is starved so no race
1113 * condition concern
1114 */
1115 audio->teos = 0;
1116
1117 rc = wait_event_interruptible(audio->write_wait,
1118 audio->teos || audio->wflush);
1119
1120 if (audio->wflush)
1121 rc = -EBUSY;
1122
1123done:
1124 mutex_unlock(&audio->write_lock);
1125done_nolock:
1126 return rc;
1127}
1128
1129static ssize_t audamrwb_read(struct file *file, char __user *buf, size_t count,
1130 loff_t *pos)
1131{
1132 struct audio *audio = file->private_data;
1133 const char __user *start = buf;
1134 int rc = 0;
1135
1136 if (!audio->pcm_feedback)
1137 return 0; /* PCM feedback is not enabled. Nothing to read */
1138
1139 mutex_lock(&audio->read_lock);
1140 MM_DBG("count %d\n", count);
1141 while (count > 0) {
1142 rc = wait_event_interruptible(audio->read_wait,
1143 (audio->in[audio->read_next].used > 0) ||
1144 (audio->stopped) || (audio->rflush));
1145
1146 if (rc < 0)
1147 break;
1148
1149 if (audio->stopped || audio->rflush) {
1150 rc = -EBUSY;
1151 break;
1152 }
1153
1154 if (count < audio->in[audio->read_next].used) {
1155 /* Read must happen in frame boundary. Since driver does
1156 * not know frame size, read count must be greater or
1157 * equal to size of PCM samples
1158 */
1159 MM_DBG("read stop - partial frame\n");
1160 break;
1161 } else {
1162 MM_DBG("read from in[%d]\n", audio->read_next);
1163
1164 if (copy_to_user
1165 (buf, audio->in[audio->read_next].data,
1166 audio->in[audio->read_next].used)) {
1167 MM_ERR("invalid addr %x\n", (unsigned int)buf);
1168 rc = -EFAULT;
1169 break;
1170 }
1171 count -= audio->in[audio->read_next].used;
1172 buf += audio->in[audio->read_next].used;
1173 audio->in[audio->read_next].used = 0;
1174 if ((++audio->read_next) == audio->pcm_buf_count)
1175 audio->read_next = 0;
1176 break;
1177 }
1178 }
1179
1180 /* don't feed output buffer to HW decoder during flushing
1181 * buffer refresh command will be sent once flush completes
1182 * send buf refresh command here can confuse HW decoder
1183 */
1184 if (audio->buf_refresh && !audio->rflush) {
1185 audio->buf_refresh = 0;
1186 MM_DBG("kick start pcm feedback again\n");
1187 audamrwb_buffer_refresh(audio);
1188 }
1189
1190 mutex_unlock(&audio->read_lock);
1191
1192 if (buf > start)
1193 rc = buf - start;
1194
1195 MM_DBG("read %d bytes\n", rc);
1196 return rc;
1197}
1198
1199static int audamrwb_process_eos(struct audio *audio,
1200 const char __user *buf_start, unsigned short mfield_size)
1201{
1202 struct buffer *frame;
1203 char *buf_ptr;
1204 int rc = 0;
1205
1206 MM_DBG("signal input EOS reserved=%d\n", audio->reserved);
1207 if (audio->reserved) {
1208 MM_DBG("Pass reserve byte\n");
1209 frame = audio->out + audio->out_head;
1210 buf_ptr = frame->data;
1211 rc = wait_event_interruptible(audio->write_wait,
1212 (frame->used == 0)
1213 || (audio->stopped)
1214 || (audio->wflush));
1215 if (rc < 0)
1216 goto done;
1217 if (audio->stopped || audio->wflush) {
1218 rc = -EBUSY;
1219 goto done;
1220 }
1221 buf_ptr[0] = audio->rsv_byte;
1222 buf_ptr[1] = 0;
1223 audio->out_head ^= 1;
1224 frame->mfield_sz = 0;
1225 audio->reserved = 0;
1226 frame->used = 2;
1227 audamrwb_send_data(audio, 0);
1228 }
1229
1230 MM_DBG("Now signal input EOS after reserved bytes %d %d %d\n",
1231 audio->out[0].used, audio->out[1].used, audio->out_needed);
1232
1233 frame = audio->out + audio->out_head;
1234
1235 rc = wait_event_interruptible(audio->write_wait,
1236 (audio->out_needed &&
1237 audio->out[0].used == 0 &&
1238 audio->out[1].used == 0)
1239 || (audio->stopped)
1240 || (audio->wflush));
1241
1242 if (rc < 0)
1243 goto done;
1244 if (audio->stopped || audio->wflush) {
1245 rc = -EBUSY;
1246 goto done;
1247 }
1248
1249 if (copy_from_user(frame->data, buf_start, mfield_size)) {
1250 rc = -EFAULT;
1251 goto done;
1252 }
1253
1254 frame->mfield_sz = mfield_size;
1255 audio->out_head ^= 1;
1256 frame->used = mfield_size;
1257 audamrwb_send_data(audio, 0);
1258
1259done:
1260 return rc;
1261}
1262
1263static ssize_t audamrwb_write(struct file *file, const char __user *buf,
1264 size_t count, loff_t *pos)
1265{
1266 struct audio *audio = file->private_data;
1267 const char __user *start = buf;
1268 struct buffer *frame;
1269 size_t xfer;
1270 char *cpy_ptr;
1271 int rc = 0, eos_condition = AUDAMRWB_EOS_NONE;
1272 unsigned short mfield_size = 0;
1273 unsigned dsize;
1274
1275 MM_DBG("cnt=%d\n", count);
1276
1277 mutex_lock(&audio->write_lock);
1278 while (count > 0) {
1279 frame = audio->out + audio->out_head;
1280 cpy_ptr = frame->data;
1281 dsize = 0;
1282 rc = wait_event_interruptible(audio->write_wait,
1283 (frame->used == 0)
1284 || (audio->stopped)
1285 || (audio->wflush));
1286
1287 MM_DBG("buffer available\n");
1288 if (rc < 0)
1289 break;
1290 if (audio->stopped || audio->wflush) {
1291 rc = -EBUSY;
1292 break;
1293 }
1294
1295 if (audio->mfield) {
1296 if (buf == start) {
1297 /* Processing beginning of user buffer */
1298 if (__get_user(mfield_size,
1299 (unsigned short __user *) buf)) {
1300 rc = -EFAULT;
1301 break;
1302 } else if (mfield_size > count) {
1303 rc = -EINVAL;
1304 break;
1305 }
1306 MM_DBG("mf offset_val %x\n", mfield_size);
1307 if (copy_from_user(cpy_ptr, buf, mfield_size)) {
1308 rc = -EFAULT;
1309 break;
1310 }
1311 /* Check if EOS flag is set and buffer
1312 * contains just meta field
1313 */
1314 if (cpy_ptr[AUDAMRWB_EOS_FLG_OFFSET] &
1315 AUDAMRWB_EOS_FLG_MASK) {
1316 MM_DBG("eos set\n");
1317 eos_condition = AUDAMRWB_EOS_SET;
1318 if (mfield_size == count) {
1319 buf += mfield_size;
1320 break;
1321 } else
1322 cpy_ptr[AUDAMRWB_EOS_FLG_OFFSET] &=
1323 ~AUDAMRWB_EOS_FLG_MASK;
1324 }
1325 cpy_ptr += mfield_size;
1326 count -= mfield_size;
1327 dsize += mfield_size;
1328 buf += mfield_size;
1329 } else {
1330 mfield_size = 0;
1331 MM_DBG("continuous buffer\n");
1332 }
1333 frame->mfield_sz = mfield_size;
1334 }
1335
1336 if (audio->reserved) {
1337 MM_DBG("append reserved byte %x\n", audio->rsv_byte);
1338 *cpy_ptr = audio->rsv_byte;
1339 xfer = (count > ((frame->size - mfield_size) - 1)) ?
1340 ((frame->size - mfield_size) - 1) : count;
1341 cpy_ptr++;
1342 dsize += 1;
1343 audio->reserved = 0;
1344 } else
1345 xfer = (count > (frame->size - mfield_size)) ?
1346 (frame->size - mfield_size) : count;
1347
1348 if (copy_from_user(cpy_ptr, buf, xfer)) {
1349 rc = -EFAULT;
1350 break;
1351 }
1352
1353 dsize += xfer;
1354 if (dsize & 1) {
1355 audio->rsv_byte = ((char *) frame->data)[dsize - 1];
1356 MM_DBG("odd length buf reserve last byte %x\n",
1357 audio->rsv_byte);
1358 audio->reserved = 1;
1359 dsize--;
1360 }
1361 count -= xfer;
1362 buf += xfer;
1363
1364 if (dsize > 0) {
1365 audio->out_head ^= 1;
1366 frame->used = dsize;
1367 audamrwb_send_data(audio, 0);
1368 }
1369 }
1370 MM_DBG("eos_condition %x buf[0x%x] start[0x%x]\n", eos_condition,
1371 (int) buf, (int) start);
1372 if (eos_condition == AUDAMRWB_EOS_SET)
1373 rc = audamrwb_process_eos(audio, start, mfield_size);
1374 mutex_unlock(&audio->write_lock);
1375 if (!rc) {
1376 if (buf > start)
1377 return buf - start;
1378 }
1379 return rc;
1380}
1381
1382static int audamrwb_release(struct inode *inode, struct file *file)
1383{
1384 struct audio *audio = file->private_data;
1385
1386 MM_INFO("audio instance 0x%08x freeing\n", (int)audio);
1387
1388 mutex_lock(&audio->lock);
1389 auddev_unregister_evt_listner(AUDDEV_CLNT_DEC, audio->dec_id);
1390 audamrwb_disable(audio);
1391 audamrwb_flush(audio);
1392 audamrwb_flush_pcm_buf(audio);
1393 msm_adsp_put(audio->audplay);
1394 audpp_adec_free(audio->dec_id);
1395#ifdef CONFIG_HAS_EARLYSUSPEND
1396 unregister_early_suspend(&audio->suspend_ctl.node);
1397#endif
1398 audio->event_abort = 1;
1399 wake_up(&audio->event_wait);
1400 audamrwb_reset_event_queue(audio);
Laura Abbott61399692012-04-30 14:25:46 -07001401 iounmap(audio->map_v_write);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301402 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001403 if (audio->read_data) {
Laura Abbott61399692012-04-30 14:25:46 -07001404 iounmap(audio->map_v_read);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301405 free_contiguous_memory_by_paddr(audio->read_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001406 }
1407 mutex_unlock(&audio->lock);
1408#ifdef CONFIG_DEBUG_FS
1409 if (audio->dentry)
1410 debugfs_remove(audio->dentry);
1411#endif
1412 kfree(audio);
1413 return 0;
1414}
1415
Vinay Vaka051db722012-01-24 19:48:32 +05301416#ifdef CONFIG_HAS_EARLYSUSPEND
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001417static void audamrwb_post_event(struct audio *audio, int type,
1418 union msm_audio_event_payload payload)
1419{
1420 struct audamrwb_event *e_node = NULL;
1421 unsigned long flags;
1422
1423 spin_lock_irqsave(&audio->event_queue_lock, flags);
1424
1425 if (!list_empty(&audio->free_event_queue)) {
1426 e_node = list_first_entry(&audio->free_event_queue,
1427 struct audamrwb_event, list);
1428 list_del(&e_node->list);
1429 } else {
1430 e_node = kmalloc(sizeof(struct audamrwb_event), GFP_ATOMIC);
1431 if (!e_node) {
1432 MM_ERR("No mem to post event %d\n", type);
1433 return;
1434 }
1435 }
1436
1437 e_node->event_type = type;
1438 e_node->payload = payload;
1439
1440 list_add_tail(&e_node->list, &audio->event_queue);
1441 spin_unlock_irqrestore(&audio->event_queue_lock, flags);
1442 wake_up(&audio->event_wait);
1443}
1444
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001445static void audamrwb_suspend(struct early_suspend *h)
1446{
1447 struct audamrwb_suspend_ctl *ctl =
1448 container_of(h, struct audamrwb_suspend_ctl, node);
1449 union msm_audio_event_payload payload;
1450
1451 MM_DBG("\n"); /* Macro prints the file name and function */
1452 audamrwb_post_event(ctl->audio, AUDIO_EVENT_SUSPEND, payload);
1453}
1454
1455static void audamrwb_resume(struct early_suspend *h)
1456{
1457 struct audamrwb_suspend_ctl *ctl =
1458 container_of(h, struct audamrwb_suspend_ctl, node);
1459 union msm_audio_event_payload payload;
1460
1461 MM_DBG("\n"); /* Macro prints the file name and function */
1462 audamrwb_post_event(ctl->audio, AUDIO_EVENT_RESUME, payload);
1463}
1464#endif
1465
1466#ifdef CONFIG_DEBUG_FS
1467static ssize_t audamrwb_debug_open(struct inode *inode, struct file *file)
1468{
1469 file->private_data = inode->i_private;
1470 return 0;
1471}
1472
1473static ssize_t audamrwb_debug_read(struct file *file, char __user *buf,
1474 size_t count, loff_t *ppos)
1475{
1476 const int debug_bufmax = 1024;
1477 static char buffer[1024];
1478 int n = 0, i;
1479 struct audio *audio = file->private_data;
1480
1481 mutex_lock(&audio->lock);
1482 n = scnprintf(buffer, debug_bufmax, "opened %d\n", audio->opened);
1483 n += scnprintf(buffer + n, debug_bufmax - n,
1484 "enabled %d\n", audio->enabled);
1485 n += scnprintf(buffer + n, debug_bufmax - n,
1486 "stopped %d\n", audio->stopped);
1487 n += scnprintf(buffer + n, debug_bufmax - n,
1488 "pcm_feedback %d\n", audio->pcm_feedback);
1489 n += scnprintf(buffer + n, debug_bufmax - n,
1490 "out_buf_sz %d\n", audio->out[0].size);
1491 n += scnprintf(buffer + n, debug_bufmax - n,
1492 "pcm_buf_count %d \n", audio->pcm_buf_count);
1493 n += scnprintf(buffer + n, debug_bufmax - n,
1494 "pcm_buf_sz %d \n", audio->in[0].size);
1495 n += scnprintf(buffer + n, debug_bufmax - n,
1496 "volume %x \n", audio->vol_pan.volume);
1497 n += scnprintf(buffer + n, debug_bufmax - n,
1498 "sample rate %d \n", audio->out_sample_rate);
1499 n += scnprintf(buffer + n, debug_bufmax - n,
1500 "channel mode %d \n", audio->out_channel_mode);
1501 mutex_unlock(&audio->lock);
1502 /* Following variables are only useful for debugging when
1503 * when playback halts unexpectedly. Thus, no mutual exclusion
1504 * enforced
1505 */
1506 n += scnprintf(buffer + n, debug_bufmax - n,
1507 "wflush %d\n", audio->wflush);
1508 n += scnprintf(buffer + n, debug_bufmax - n,
1509 "rflush %d\n", audio->rflush);
1510 n += scnprintf(buffer + n, debug_bufmax - n,
1511 "running %d \n", audio->running);
1512 n += scnprintf(buffer + n, debug_bufmax - n,
1513 "dec state %d \n", audio->dec_state);
1514 n += scnprintf(buffer + n, debug_bufmax - n,
1515 "out_needed %d \n", audio->out_needed);
1516 n += scnprintf(buffer + n, debug_bufmax - n,
1517 "out_head %d \n", audio->out_head);
1518 n += scnprintf(buffer + n, debug_bufmax - n,
1519 "out_tail %d \n", audio->out_tail);
1520 n += scnprintf(buffer + n, debug_bufmax - n,
1521 "out[0].used %d \n", audio->out[0].used);
1522 n += scnprintf(buffer + n, debug_bufmax - n,
1523 "out[1].used %d \n", audio->out[1].used);
1524 n += scnprintf(buffer + n, debug_bufmax - n,
1525 "buffer_refresh %d \n", audio->buf_refresh);
1526 n += scnprintf(buffer + n, debug_bufmax - n,
1527 "read_next %d \n", audio->read_next);
1528 n += scnprintf(buffer + n, debug_bufmax - n,
1529 "fill_next %d \n", audio->fill_next);
1530 for (i = 0; i < audio->pcm_buf_count; i++)
1531 n += scnprintf(buffer + n, debug_bufmax - n,
1532 "in[%d].used %d \n", i, audio->in[i].used);
1533 buffer[n] = 0;
1534 return simple_read_from_buffer(buf, count, ppos, buffer, n);
1535}
1536
1537static const struct file_operations audamrwb_debug_fops = {
1538 .read = audamrwb_debug_read,
1539 .open = audamrwb_debug_open,
1540};
1541#endif
1542
1543static int audamrwb_open(struct inode *inode, struct file *file)
1544{
1545 struct audio *audio = NULL;
1546 int rc, dec_attrb, decid, i;
1547 struct audamrwb_event *e_node = NULL;
1548#ifdef CONFIG_DEBUG_FS
1549 /* 4 bytes represents decoder number, 1 byte for terminate string */
1550 char name[sizeof "msm_amrwb_" + 5];
1551#endif
1552
1553 /* Allocate Mem for audio instance */
1554 audio = kzalloc(sizeof(struct audio), GFP_KERNEL);
1555 if (!audio) {
1556 MM_ERR("no memory to allocate audio instance\n");
1557 rc = -ENOMEM;
1558 goto done;
1559 }
1560 MM_INFO("audio instance 0x%08x created\n", (int)audio);
1561
1562 /* Allocate the decoder */
1563 dec_attrb = AUDDEC_DEC_AMRWB;
1564 if (file->f_mode & FMODE_READ)
1565 dec_attrb |= MSM_AUD_MODE_NONTUNNEL;
1566 else
1567 dec_attrb |= MSM_AUD_MODE_TUNNEL;
1568
1569 decid = audpp_adec_alloc(dec_attrb, &audio->module_name,
1570 &audio->queue_id);
1571
1572 if (decid < 0) {
1573 MM_ERR("No free decoder available, freeing instance 0x%08x\n",
1574 (int)audio);
1575 rc = -ENODEV;
1576 kfree(audio);
1577 goto done;
1578 }
1579
1580 audio->dec_id = decid & MSM_AUD_DECODER_MASK;
1581
Santosh Mardifdc227a2011-07-11 17:20:34 +05301582 audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K);
1583 if (!audio->phys) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001584 MM_ERR("could not allocate write buffers, freeing instance \
1585 0x%08x\n", (int)audio);
1586 rc = -ENOMEM;
1587 audpp_adec_free(audio->dec_id);
1588 kfree(audio);
1589 goto done;
1590 } else {
Laura Abbott61399692012-04-30 14:25:46 -07001591 audio->map_v_write = ioremap(audio->phys, DMASZ);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301592 if (IS_ERR(audio->map_v_write)) {
1593 MM_ERR("could not map write phys buffers, freeing \
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001594 instance 0x%08x\n", (int)audio);
1595 rc = -ENOMEM;
Santosh Mardifdc227a2011-07-11 17:20:34 +05301596 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001597 audpp_adec_free(audio->dec_id);
1598 kfree(audio);
1599 goto done;
1600 }
Laura Abbott61399692012-04-30 14:25:46 -07001601 audio->data = audio->map_v_write;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001602 MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
1603 audio->phys, (int)audio->data);
1604 }
1605
1606 rc = msm_adsp_get(audio->module_name, &audio->audplay,
1607 &audplay_adsp_ops_amrwb, audio);
1608 if (rc) {
1609 MM_ERR("failed to get %s module freeing instance 0x%08x\n",
1610 audio->module_name, (int)audio);
1611 goto err;
1612 }
1613
1614 mutex_init(&audio->lock);
1615 mutex_init(&audio->write_lock);
1616 mutex_init(&audio->read_lock);
1617 mutex_init(&audio->get_event_lock);
1618 spin_lock_init(&audio->dsp_lock);
1619 spin_lock_init(&audio->event_queue_lock);
1620 INIT_LIST_HEAD(&audio->free_event_queue);
1621 INIT_LIST_HEAD(&audio->event_queue);
1622 init_waitqueue_head(&audio->write_wait);
1623 init_waitqueue_head(&audio->read_wait);
1624 init_waitqueue_head(&audio->wait);
1625 init_waitqueue_head(&audio->event_wait);
1626 init_waitqueue_head(&audio->avsync_wait);
1627
1628 audio->out[0].data = audio->data + 0;
1629 audio->out[0].addr = audio->phys + 0;
1630 audio->out[0].size = BUFSZ;
1631
1632 audio->out[1].data = audio->data + BUFSZ;
1633 audio->out[1].addr = audio->phys + BUFSZ;
1634 audio->out[1].size = BUFSZ;
1635
1636 audio->vol_pan.volume = 0x2000;
1637 audio->vol_pan.pan = 0x0;
1638 audio->eq_enable = 0;
1639 audio->out_sample_rate = 44100;
1640 audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
1641
1642 audamrwb_flush(audio);
1643
1644 file->private_data = audio;
1645 audio->opened = 1;
1646 audio->event_abort = 0;
1647 audio->device_events = AUDDEV_EVT_DEV_RDY
1648 |AUDDEV_EVT_DEV_RLS|
1649 AUDDEV_EVT_STREAM_VOL_CHG;
1650
1651 rc = auddev_register_evt_listner(audio->device_events,
1652 AUDDEV_CLNT_DEC,
1653 audio->dec_id,
1654 amrwb_listner,
1655 (void *)audio);
1656 if (rc) {
1657 MM_ERR("failed to register listner\n");
1658 goto event_err;
1659 }
1660
1661#ifdef CONFIG_DEBUG_FS
1662 snprintf(name, sizeof name, "msm_amrwb_%04x", audio->dec_id);
1663 audio->dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
1664 NULL, (void *) audio, &audamrwb_debug_fops);
1665
1666 if (IS_ERR(audio->dentry))
1667 MM_DBG("debugfs_create_file failed\n");
1668#endif
1669#ifdef CONFIG_HAS_EARLYSUSPEND
1670 audio->suspend_ctl.node.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
1671 audio->suspend_ctl.node.resume = audamrwb_resume;
1672 audio->suspend_ctl.node.suspend = audamrwb_suspend;
1673 audio->suspend_ctl.audio = audio;
1674 register_early_suspend(&audio->suspend_ctl.node);
1675#endif
1676 for (i = 0; i < AUDAMRWB_EVENT_NUM; i++) {
1677 e_node = kmalloc(sizeof(struct audamrwb_event), GFP_KERNEL);
1678 if (e_node)
1679 list_add_tail(&e_node->list, &audio->free_event_queue);
1680 else {
1681 MM_ERR("event pkt alloc failed\n");
1682 break;
1683 }
1684 }
1685done:
1686 return rc;
1687event_err:
1688 msm_adsp_put(audio->audplay);
1689err:
Laura Abbott61399692012-04-30 14:25:46 -07001690 iounmap(audio->map_v_write);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301691 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001692 audpp_adec_free(audio->dec_id);
1693 kfree(audio);
1694 return rc;
1695}
1696
1697static const struct file_operations audio_amrwb_fops = {
1698 .owner = THIS_MODULE,
1699 .open = audamrwb_open,
1700 .release = audamrwb_release,
1701 .read = audamrwb_read,
1702 .write = audamrwb_write,
1703 .unlocked_ioctl = audamrwb_ioctl,
1704 .fsync = audamrwb_fsync,
1705};
1706
1707struct miscdevice audio_amrwb_misc = {
1708 .minor = MISC_DYNAMIC_MINOR,
1709 .name = "msm_amrwb",
1710 .fops = &audio_amrwb_fops,
1711};
1712
1713static int __init audamrwb_init(void)
1714{
1715 return misc_register(&audio_amrwb_misc);
1716}
1717
1718static void __exit audamrwb_exit(void)
1719{
1720 misc_deregister(&audio_amrwb_misc);
1721}
1722
1723module_init(audamrwb_init);
1724module_exit(audamrwb_exit);
1725
1726MODULE_DESCRIPTION("MSM AMR-WB driver");
1727MODULE_LICENSE("GPL v2");