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