blob: 7a5536a5c1db88dde1e052801fa0079c0b73edb7 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* arch/arm/mach-msm/qdsp5/audio_evrc_in.c
2 *
3 * evrc audio input device
4 *
5 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
6 *
7 * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_evrc_in.c,
8 * Copyright (C) 2008 Google, Inc.
9 * Copyright (C) 2008 HTC Corporation
10 *
11 * This software is licensed under the terms of the GNU General Public
12 * License version 2, as published by the Free Software Foundation, and
13 * may be copied, distributed, and modified under those terms.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/fs.h>
24#include <linux/miscdevice.h>
25#include <linux/uaccess.h>
26#include <linux/kthread.h>
27#include <linux/wait.h>
28#include <linux/dma-mapping.h>
29
30#include <linux/delay.h>
31
32#include <linux/msm_audio_qcp.h>
33
Santosh Mardi7faa0fa2011-09-22 15:32:23 +053034
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070035#include <linux/memory_alloc.h>
36
37#include <asm/atomic.h>
38#include <asm/ioctls.h>
Santosh Mardi7faa0fa2011-09-22 15:32:23 +053039#include <mach/msm_memtypes.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070040#include <mach/msm_adsp.h>
41#include <mach/msm_rpcrouter.h>
Santosh Mardi7faa0fa2011-09-22 15:32:23 +053042#include <mach/iommu.h>
43#include <mach/iommu_domains.h>
44#include <mach/msm_subsystem_map.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070045
46#include "audmgr.h"
47
48#include <mach/qdsp5/qdsp5audpreproc.h>
49#include <mach/qdsp5/qdsp5audpreproccmdi.h>
50#include <mach/qdsp5/qdsp5audpreprocmsg.h>
51#include <mach/qdsp5/qdsp5audreccmdi.h>
52#include <mach/qdsp5/qdsp5audrecmsg.h>
53#include <mach/debug_mm.h>
54
55#define FRAME_HEADER_SIZE 8 /* 8 bytes frame header */
56#define NT_FRAME_HEADER_SIZE 24 /* 24 bytes frame header */
57/* FRAME_NUM must be a power of two */
58#define FRAME_NUM 8
59#define EVRC_FRAME_SIZE 36 /* 36 bytes data */
60/*Tunnel mode : 36 bytes data + 8 byte header*/
61#define FRAME_SIZE (EVRC_FRAME_SIZE + FRAME_HEADER_SIZE)
62 /* 36 bytes data + 24 meta field*/
63#define NT_FRAME_SIZE (EVRC_FRAME_SIZE + NT_FRAME_HEADER_SIZE)
64#define DMASZ (FRAME_SIZE * FRAME_NUM)
65#define NT_DMASZ (NT_FRAME_SIZE * FRAME_NUM)
66#define OUT_FRAME_NUM 2
67#define OUT_BUFFER_SIZE (4 * 1024 + NT_FRAME_HEADER_SIZE)
68#define BUFFER_SIZE (OUT_BUFFER_SIZE * OUT_FRAME_NUM)
69
70#define AUDPREPROC_EVRC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer*/
71#define AUDPREPROC_EVRC_EOS_FLG_MASK 0x01
72#define AUDPREPROC_EVRC_EOS_NONE 0x0 /* No EOS detected */
73#define AUDPREPROC_EVRC_EOS_SET 0x1 /* EOS set in meta field */
74
75struct buffer {
76 void *data;
77 uint32_t size;
78 uint32_t read;
79 uint32_t addr;
80 uint32_t used;
81 uint32_t mfield_sz;
82};
83
84struct audio_evrc_in {
85 struct buffer in[FRAME_NUM];
86
87 spinlock_t dsp_lock;
88
89 atomic_t in_bytes;
90 atomic_t in_samples;
91
92 struct mutex lock;
93 struct mutex read_lock;
94 wait_queue_head_t wait;
95 wait_queue_head_t wait_enable;
96 /*write section*/
97 struct buffer out[OUT_FRAME_NUM];
98
99 uint8_t out_head;
100 uint8_t out_tail;
101 uint8_t out_needed; /* number of buffers the dsp is waiting for */
102 uint32_t out_count;
103
104 struct mutex write_lock;
105 wait_queue_head_t write_wait;
106 int32_t out_phys; /* physical address of write buffer */
107 char *out_data;
108 int mfield; /* meta field embedded in data */
109 int wflush; /*write flush */
110 int rflush; /*read flush*/
111 int out_frame_cnt;
112
113 struct msm_adsp_module *audrec;
114 struct msm_adsp_module *audpre;
115
116
117 /* configuration to use on next enable */
118 uint32_t samp_rate;
119 uint32_t channel_mode;
120 uint32_t buffer_size; /* Frame size (36 bytes) */
121 uint32_t enc_type; /* 11 for EVRC */
122 uint32_t mode; /* T or NT Mode*/
123
124 struct msm_audio_evrc_enc_config cfg;
125
126 uint32_t dsp_cnt;
127 uint32_t in_head; /* next buffer dsp will write */
128 uint32_t in_tail; /* next buffer read() will read */
129 uint32_t in_count; /* number of buffers available to read() */
130
131 uint32_t eos_ack;
132 uint32_t flush_ack;
133
134 const char *module_name;
135 unsigned queue_ids;
136 uint16_t enc_id; /* Session Id */
137
138 unsigned short samp_rate_index;
139 uint32_t audrec_obj_idx ;
140
141 struct audmgr audmgr;
142
143 /* data allocated for various buffers */
144 char *data;
145 dma_addr_t phys;
146
Santosh Mardi7faa0fa2011-09-22 15:32:23 +0530147 struct msm_mapped_buffer *map_v_read;
148 struct msm_mapped_buffer *map_v_write;
149
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700150 int opened;
151 int enabled;
152 int running;
153 int stopped; /* set when stopped, cleared on flush */
154};
155
156struct audio_frame {
157 uint16_t frame_count_lsw;
158 uint16_t frame_count_msw;
159 uint16_t frame_length;
160 uint16_t erased_pcm;
161 unsigned char raw_bitstream[];
162} __packed;
163
164struct audio_frame_nt {
165 uint16_t metadata_len;
166 uint16_t frame_count_lsw;
167 uint16_t frame_count_msw;
168 uint16_t frame_length;
169 uint16_t erased_pcm;
170 uint16_t reserved;
171 uint16_t time_stamp_dword_lsw;
172 uint16_t time_stamp_dword_msw;
173 uint16_t time_stamp_lsw;
174 uint16_t time_stamp_msw;
175 uint16_t nflag_lsw;
176 uint16_t nflag_msw;
177 unsigned char raw_bitstream[]; /* samples */
178} __packed;
179
180struct evrc_encoded_meta_out {
181 uint16_t metadata_len;
182 uint16_t time_stamp_dword_lsw;
183 uint16_t time_stamp_dword_msw;
184 uint16_t time_stamp_lsw;
185 uint16_t time_stamp_msw;
186 uint16_t nflag_lsw;
187 uint16_t nflag_msw;
188};
189
190/* Audrec Queue command sent macro's */
191#define audio_send_queue_pre(audio, cmd, len) \
192 msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len)
193
194#define audio_send_queue_recbs(audio, cmd, len) \
195 msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\
196 cmd, len)
197#define audio_send_queue_rec(audio, cmd, len) \
198 msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\
199 cmd, len)
200
201static int audevrc_in_dsp_enable(struct audio_evrc_in *audio, int enable);
202static int audevrc_in_encparam_config(struct audio_evrc_in *audio);
203static int audevrc_in_encmem_config(struct audio_evrc_in *audio);
204static int audevrc_in_dsp_read_buffer(struct audio_evrc_in *audio,
205 uint32_t read_cnt);
206static void audevrc_in_flush(struct audio_evrc_in *audio);
207
208static void audevrc_in_get_dsp_frames(struct audio_evrc_in *audio);
209static int audpcm_config(struct audio_evrc_in *audio);
210static void audevrc_out_flush(struct audio_evrc_in *audio);
211static int audevrc_in_routing_mode_config(struct audio_evrc_in *audio);
212static void audrec_pcm_send_data(struct audio_evrc_in *audio, unsigned needed);
213static void audevrc_nt_in_get_dsp_frames(struct audio_evrc_in *audio);
214static void audevrc_in_flush(struct audio_evrc_in *audio);
215
216static unsigned convert_samp_index(unsigned index)
217{
218 switch (index) {
219 case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000;
220 case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100;
221 case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000;
222 case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000;
223 case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050;
224 case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000;
225 case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000;
226 case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025;
227 case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000;
228 default: return 11025;
229 }
230}
231
232/* must be called with audio->lock held */
233static int audevrc_in_enable(struct audio_evrc_in *audio)
234{
235 struct audmgr_config cfg;
236 int rc;
237
238 if (audio->enabled)
239 return 0;
240
241 cfg.tx_rate = audio->samp_rate;
242 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
243 cfg.def_method = RPC_AUD_DEF_METHOD_RECORD;
244 cfg.codec = RPC_AUD_DEF_CODEC_EVRC;
245 cfg.snd_method = RPC_SND_METHOD_MIDI;
246
247 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
248 rc = audmgr_enable(&audio->audmgr, &cfg);
249 if (rc < 0)
250 return rc;
251
252 if (msm_adsp_enable(audio->audpre)) {
253 audmgr_disable(&audio->audmgr);
254 MM_ERR("msm_adsp_enable(audpre) failed\n");
255 return -ENODEV;
256 }
257 }
258 if (msm_adsp_enable(audio->audrec)) {
259 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
260 audmgr_disable(&audio->audmgr);
261 msm_adsp_disable(audio->audpre);
262 }
263 MM_ERR("msm_adsp_enable(audrec) failed\n");
264 return -ENODEV;
265 }
266
267 audio->enabled = 1;
268 audevrc_in_dsp_enable(audio, 1);
269
270 return 0;
271}
272
273/* must be called with audio->lock held */
274static int audevrc_in_disable(struct audio_evrc_in *audio)
275{
276 if (audio->enabled) {
277 audio->enabled = 0;
278
279 audevrc_in_dsp_enable(audio, 0);
280
281 wake_up(&audio->wait);
282 wait_event_interruptible_timeout(audio->wait_enable,
283 audio->running == 0, 1*HZ);
284 msm_adsp_disable(audio->audrec);
285 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
286 msm_adsp_disable(audio->audpre);
287 audmgr_disable(&audio->audmgr);
288 }
289 }
290 return 0;
291}
292
293/* ------------------- dsp --------------------- */
294static void audpre_dsp_event(void *data, unsigned id, size_t len,
295 void (*getevent)(void *ptr, size_t len))
296{
297 uint16_t msg[2];
298 getevent(msg, sizeof(msg));
299
300 switch (id) {
301 case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
302 MM_DBG("type %d, status_flag %d\n", msg[0], msg[1]);
303 break;
304 case AUDPREPROC_MSG_ERROR_MSG_ID:
305 MM_ERR("err_index %d\n", msg[0]);
306 break;
307 case ADSP_MESSAGE_ID:
308 MM_DBG("Received ADSP event: module enable(audpreproctask)\n");
309 break;
310 default:
311 MM_ERR("unknown event %d\n", id);
312 }
313}
314
315static void audevrc_in_get_dsp_frames(struct audio_evrc_in *audio)
316{
317 struct audio_frame *frame;
318 uint32_t index;
319 unsigned long flags;
320
321 index = audio->in_head;
322
323 frame = (void *) (((char *)audio->in[index].data) -
324 sizeof(*frame));
325 spin_lock_irqsave(&audio->dsp_lock, flags);
326 audio->in[index].size = frame->frame_length;
327
328 /* statistics of read */
329 atomic_add(audio->in[index].size, &audio->in_bytes);
330 atomic_add(1, &audio->in_samples);
331
332 audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1);
333
334 /* If overflow, move the tail index foward. */
335 if (audio->in_head == audio->in_tail) {
336 MM_ERR("Error! not able to keep up the read\n");
337 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
338 MM_ERR("in_count = %d\n", audio->in_count);
339 } else
340 audio->in_count++;
341
342 audevrc_in_dsp_read_buffer(audio, audio->dsp_cnt++);
343 spin_unlock_irqrestore(&audio->dsp_lock, flags);
344
345 wake_up(&audio->wait);
346}
347
348static void audevrc_nt_in_get_dsp_frames(struct audio_evrc_in *audio)
349{
350 struct audio_frame_nt *nt_frame;
351 uint32_t index;
352 unsigned long flags;
353
354 index = audio->in_head;
355 nt_frame = (void *) (((char *)audio->in[index].data) - \
356 sizeof(struct audio_frame_nt));
357 spin_lock_irqsave(&audio->dsp_lock, flags);
358 audio->in[index].size = nt_frame->frame_length;
359 /* statistics of read */
360 atomic_add(audio->in[index].size, &audio->in_bytes);
361 atomic_add(1, &audio->in_samples);
362
363 audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1);
364
365 /* If overflow, move the tail index foward. */
366 if (audio->in_head == audio->in_tail)
367 MM_DBG("Error! not able to keep up the read\n");
368 else
369 audio->in_count++;
370
371 spin_unlock_irqrestore(&audio->dsp_lock, flags);
372 wake_up(&audio->wait);
373}
374
375static int audrec_pcm_buffer_ptr_refresh(struct audio_evrc_in *audio,
376 unsigned idx, unsigned len)
377{
378 struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc cmd;
379
380 if (len == NT_FRAME_HEADER_SIZE)
381 len = len / 2;
382 else
383 len = (len + NT_FRAME_HEADER_SIZE) / 2;
384 MM_DBG("len = %d\n", len);
385 memset(&cmd, 0, sizeof(cmd));
386 cmd.cmd_id = AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC;
387 cmd.num_buffers = 1;
388 if (cmd.num_buffers == 1) {
389 cmd.buf_address_length[0] = (audio->out[idx].addr &
390 0xffff0000) >> 16;
391 cmd.buf_address_length[1] = (audio->out[idx].addr &
392 0x0000ffff);
393 cmd.buf_address_length[2] = (len & 0xffff0000) >> 16;
394 cmd.buf_address_length[3] = (len & 0x0000ffff);
395 }
396 audio->out_frame_cnt++;
397 return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
398}
399
400static int audpcm_config(struct audio_evrc_in *audio)
401{
402 struct audrec_cmd_pcm_cfg_arm_to_enc cmd;
403 MM_DBG("\n");
404 memset(&cmd, 0, sizeof(cmd));
405 cmd.cmd_id = AUDREC_CMD_PCM_CFG_ARM_TO_ENC;
406 cmd.config_update_flag = AUDREC_PCM_CONFIG_UPDATE_FLAG_ENABLE;
407 cmd.enable_flag = AUDREC_ENABLE_FLAG_VALUE;
408 cmd.sampling_freq = convert_samp_index(audio->samp_rate);
409 if (!audio->channel_mode)
410 cmd.channels = 1;
411 else
412 cmd.channels = 2;
413 cmd.frequency_of_intimation = 1;
414 cmd.max_number_of_buffers = OUT_FRAME_NUM;
415 return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
416}
417
418
419static int audevrc_in_routing_mode_config(struct audio_evrc_in *audio)
420{
421 struct audrec_cmd_routing_mode cmd;
422
423 MM_DBG("\n");
424 memset(&cmd, 0, sizeof(cmd));
425 cmd.cmd_id = AUDREC_CMD_ROUTING_MODE;
426 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)
427 cmd.routing_mode = 1;
428 return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
429}
430
431static void audrec_dsp_event(void *data, unsigned id, size_t len,
432 void (*getevent)(void *ptr, size_t len))
433{
434 struct audio_evrc_in *audio = NULL;
435
436 if (data)
437 audio = data;
438 else {
439 MM_ERR("invalid data for event %x\n", id);
440 return;
441 }
442
443 switch (id) {
444 case AUDREC_MSG_CMD_CFG_DONE_MSG: {
445 struct audrec_msg_cmd_cfg_done_msg cmd_cfg_done_msg;
446 getevent(&cmd_cfg_done_msg, AUDREC_MSG_CMD_CFG_DONE_MSG_LEN);
447 if (cmd_cfg_done_msg.audrec_enc_type & \
448 AUDREC_MSG_CFG_DONE_ENC_ENA) {
449 audio->audrec_obj_idx = cmd_cfg_done_msg.audrec_obj_idx;
450 MM_DBG("CFG ENABLED\n");
451 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
452 MM_DBG("routing command\n");
453 audevrc_in_routing_mode_config(audio);
454 } else {
455 audevrc_in_encmem_config(audio);
456 }
457 } else {
458 MM_DBG("CFG SLEEP\n");
459 audio->running = 0;
460 wake_up(&audio->wait_enable);
461 }
462 break;
463 }
464 case AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG: {
465 struct audrec_msg_cmd_routing_mode_done_msg \
466 routing_msg;
467 getevent(&routing_msg, AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG);
468 MM_DBG("AUDREC_MSG_CMD_ROUTING_MODE_DONE_MSG");
469 if (routing_msg.configuration == 0) {
470 MM_ERR("routing configuration failed\n");
471 audio->running = 0;
472 wake_up(&audio->wait_enable);
473 } else
474 audevrc_in_encmem_config(audio);
475 break;
476 }
477 case AUDREC_MSG_CMD_AREC_MEM_CFG_DONE_MSG: {
478 MM_DBG("AREC_MEM_CFG_DONE_MSG\n");
479 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
480 audevrc_in_encparam_config(audio);
481 else
482 audpcm_config(audio);
483 break;
484 }
485 case AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG: {
486 MM_DBG("AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG");
487 audevrc_in_encparam_config(audio);
488 break;
489 }
490 case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: {
491 MM_DBG("AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG\n");
492 audio->running = 1;
493 wake_up(&audio->wait_enable);
494 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)
495 audrec_pcm_send_data(audio, 1);
496 break;
497 }
498 case AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG: {
499 MM_DBG("ptr_update recieved from DSP\n");
500 audrec_pcm_send_data(audio, 1);
501 break;
502 }
503 case AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG: {
504 struct audrec_msg_no_ext_pkt_avail_msg err_msg;
505 getevent(&err_msg, AUDREC_MSG_NO_EXT_PKT_AVAILABLE_MSG_LEN);
506 MM_DBG("NO_EXT_PKT_AVAILABLE_MSG %x\n",\
507 err_msg.audrec_err_id);
508 break;
509 }
510 case AUDREC_MSG_PACKET_READY_MSG: {
511 struct audrec_msg_packet_ready_msg pkt_ready_msg;
512
513 getevent(&pkt_ready_msg, AUDREC_MSG_PACKET_READY_MSG_LEN);
514 MM_DBG("UP_PACKET_READY_MSG: write cnt msw %d \
515 write cnt lsw %d read cnt msw %d read cnt lsw %d \n",\
516 pkt_ready_msg.pkt_counter_msw, \
517 pkt_ready_msg.pkt_counter_lsw, \
518 pkt_ready_msg.pkt_read_cnt_msw, \
519 pkt_ready_msg.pkt_read_cnt_lsw);
520
521 audevrc_in_get_dsp_frames(audio);
522 break;
523 }
524 case AUDREC_UP_NT_PACKET_READY_MSG: {
525 struct audrec_up_nt_packet_ready_msg pkt_ready_msg;
526
527 getevent(&pkt_ready_msg, AUDREC_UP_NT_PACKET_READY_MSG_LEN);
528 MM_DBG("UP_NT_PACKET_READY_MSG: write cnt lsw %d \
529 write cnt msw %d read cnt lsw %d read cnt msw %d \n",\
530 pkt_ready_msg.audrec_packetwrite_cnt_lsw, \
531 pkt_ready_msg.audrec_packetwrite_cnt_msw, \
532 pkt_ready_msg.audrec_upprev_readcount_lsw, \
533 pkt_ready_msg.audrec_upprev_readcount_msw);
534
535 audevrc_nt_in_get_dsp_frames(audio);
536 break;
537 }
538 case AUDREC_CMD_FLUSH_DONE_MSG: {
539 audio->wflush = 0;
540 audio->rflush = 0;
541 audio->flush_ack = 1;
542 wake_up(&audio->write_wait);
543 MM_DBG("flush ack recieved\n");
544 break;
545 }
546 case ADSP_MESSAGE_ID:
547 MM_DBG("Received ADSP event: module \
548 enable/disable(audrectask)\n");
549 break;
550 default:
551 MM_ERR("unknown event %d\n", id);
552 }
553}
554
555static struct msm_adsp_ops audpre_evrc_adsp_ops = {
556 .event = audpre_dsp_event,
557};
558
559static struct msm_adsp_ops audrec_evrc_adsp_ops = {
560 .event = audrec_dsp_event,
561};
562
563static int audevrc_in_dsp_enable(struct audio_evrc_in *audio, int enable)
564{
565 struct audrec_cmd_enc_cfg cmd;
566
567 memset(&cmd, 0, sizeof(cmd));
568 cmd.cmd_id = AUDREC_CMD_ENC_CFG;
569 cmd.audrec_enc_type = (audio->enc_type & 0xFF) |
570 (enable ? AUDREC_CMD_ENC_ENA : AUDREC_CMD_ENC_DIS);
571 /* Don't care */
572 cmd.audrec_obj_idx = audio->audrec_obj_idx;
573
574 return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
575}
576
577static int audevrc_in_encmem_config(struct audio_evrc_in *audio)
578{
579 struct audrec_cmd_arecmem_cfg cmd;
580 uint16_t *data = (void *) audio->data;
581 int n;
582 int header_len = 0;
583
584 memset(&cmd, 0, sizeof(cmd));
585
586 cmd.cmd_id = AUDREC_CMD_ARECMEM_CFG;
587 cmd.audrec_obj_idx = audio->audrec_obj_idx;
588 /* Rate at which packet complete message comes */
589 cmd.audrec_up_pkt_intm_cnt = 1;
590 cmd.audrec_extpkt_buffer_msw = audio->phys >> 16;
591 cmd.audrec_extpkt_buffer_lsw = audio->phys;
592 /* Max Buffer no available for frames */
593 cmd.audrec_extpkt_buffer_num = FRAME_NUM;
594
595 /* prepare buffer pointers:
596 * T:36 bytes evrc packet + 4 halfword header
597 * NT:36 bytes evrc packet + 12 halfword header
598 */
599 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
600 header_len = FRAME_HEADER_SIZE/2;
601 else
602 header_len = NT_FRAME_HEADER_SIZE/2;
603
604 for (n = 0; n < FRAME_NUM; n++) {
605 audio->in[n].data = data + header_len;
606 data += (EVRC_FRAME_SIZE/2) + header_len;
607 MM_DBG("0x%8x\n", (int)(audio->in[n].data - header_len*2));
608 }
609
610 return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
611}
612
613static int audevrc_in_encparam_config(struct audio_evrc_in *audio)
614{
615 struct audrec_cmd_arecparam_evrc_cfg cmd;
616
617 memset(&cmd, 0, sizeof(cmd));
618 cmd.common.cmd_id = AUDREC_CMD_ARECPARAM_CFG;
619 cmd.common.audrec_obj_idx = audio->audrec_obj_idx;
620 cmd.enc_min_rate = audio->cfg.min_bit_rate;
621 cmd.enc_max_rate = audio->cfg.max_bit_rate;
622 cmd.rate_modulation_cmd = 0; /* Default set to 0 */
623
624 return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
625}
626
627static int audevrc_flush_command(struct audio_evrc_in *audio)
628{
629 struct audrec_cmd_flush cmd;
630 MM_DBG("\n");
631 memset(&cmd, 0, sizeof(cmd));
632 cmd.cmd_id = AUDREC_CMD_FLUSH;
633 return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
634}
635
636static int audevrc_in_dsp_read_buffer(struct audio_evrc_in *audio,
637 uint32_t read_cnt)
638{
639 audrec_cmd_packet_ext_ptr cmd;
640
641 memset(&cmd, 0, sizeof(cmd));
642 cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR;
643 cmd.type = audio->audrec_obj_idx;
644 cmd.curr_rec_count_msw = read_cnt >> 16;
645 cmd.curr_rec_count_lsw = read_cnt;
646
647 return audio_send_queue_recbs(audio, &cmd, sizeof(cmd));
648}
649
650/* ------------------- device --------------------- */
651
652static void audevrc_ioport_reset(struct audio_evrc_in *audio)
653{
654 /* Make sure read/write thread are free from
655 * sleep and knowing that system is not able
656 * to process io request at the moment
657 */
658 wake_up(&audio->write_wait);
659 mutex_lock(&audio->write_lock);
660 audevrc_in_flush(audio);
661 mutex_unlock(&audio->write_lock);
662 wake_up(&audio->wait);
663 mutex_lock(&audio->read_lock);
664 audevrc_out_flush(audio);
665 mutex_unlock(&audio->read_lock);
666}
667
668static void audevrc_in_flush(struct audio_evrc_in *audio)
669{
670 int i;
671
672 audio->dsp_cnt = 0;
673 audio->in_head = 0;
674 audio->in_tail = 0;
675 audio->in_count = 0;
676 audio->eos_ack = 0;
677 for (i = FRAME_NUM-1; i >= 0; i--) {
678 audio->in[i].size = 0;
679 audio->in[i].read = 0;
680 }
681 MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes));
682 MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples));
683 atomic_set(&audio->in_bytes, 0);
684 atomic_set(&audio->in_samples, 0);
685}
686
687static void audevrc_out_flush(struct audio_evrc_in *audio)
688{
689 int i;
690
691 audio->out_head = 0;
692 audio->out_tail = 0;
693 audio->out_count = 0;
694 for (i = OUT_FRAME_NUM-1; i >= 0; i--) {
695 audio->out[i].size = 0;
696 audio->out[i].read = 0;
697 audio->out[i].used = 0;
698 }
699}
700
701/* ------------------- device --------------------- */
702static long audevrc_in_ioctl(struct file *file,
703 unsigned int cmd, unsigned long arg)
704{
705 struct audio_evrc_in *audio = file->private_data;
706 int rc = 0;
707
708 MM_DBG("\n");
709 if (cmd == AUDIO_GET_STATS) {
710 struct msm_audio_stats stats;
711 stats.byte_count = atomic_read(&audio->in_bytes);
712 stats.sample_count = atomic_read(&audio->in_samples);
713 if (copy_to_user((void *) arg, &stats, sizeof(stats)))
714 return -EFAULT;
715 return rc;
716 }
717
718 mutex_lock(&audio->lock);
719 switch (cmd) {
720 case AUDIO_START: {
721 rc = audevrc_in_enable(audio);
722 if (!rc) {
723 rc =
724 wait_event_interruptible_timeout(audio->wait_enable,
725 audio->running != 0, 1*HZ);
726 MM_DBG("state %d rc = %d\n", audio->running, rc);
727
728 if (audio->running == 0)
729 rc = -ENODEV;
730 else
731 rc = 0;
732 }
733 audio->stopped = 0;
734 break;
735 }
736 case AUDIO_STOP: {
737 rc = audevrc_in_disable(audio);
738 audio->stopped = 1;
739 break;
740 }
741 case AUDIO_FLUSH: {
742 MM_DBG("AUDIO_FLUSH\n");
743 audio->rflush = 1;
744 audio->wflush = 1;
745 audevrc_ioport_reset(audio);
746 if (audio->running) {
747 audevrc_flush_command(audio);
748 rc = wait_event_interruptible(audio->write_wait,
749 !audio->wflush);
750 if (rc < 0) {
751 MM_ERR("AUDIO_FLUSH interrupted\n");
752 rc = -EINTR;
753 }
754 } else {
755 audio->rflush = 0;
756 audio->wflush = 0;
757 }
758 break;
759 }
760 case AUDIO_GET_CONFIG: {
761 struct msm_audio_config cfg;
762 memset(&cfg, 0, sizeof(cfg));
763 cfg.buffer_size = OUT_BUFFER_SIZE;
764 cfg.buffer_count = OUT_FRAME_NUM;
765 cfg.sample_rate = convert_samp_index(audio->samp_rate);
766 cfg.channel_count = 1;
767 cfg.type = 0;
768 cfg.unused[0] = 0;
769 cfg.unused[1] = 0;
770 cfg.unused[2] = 0;
771 if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
772 rc = -EFAULT;
773 else
774 rc = 0;
775 break;
776 }
777 case AUDIO_GET_STREAM_CONFIG: {
778 struct msm_audio_stream_config cfg;
779 memset(&cfg, 0, sizeof(cfg));
780 cfg.buffer_size = audio->buffer_size;
781 cfg.buffer_count = FRAME_NUM;
782 if (copy_to_user((void *)arg, &cfg, sizeof(cfg)))
783 rc = -EFAULT;
784 else
785 rc = 0;
786 break;
787 }
788 case AUDIO_SET_STREAM_CONFIG: {
789 struct msm_audio_stream_config cfg;
790 if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
791 rc = -EFAULT;
792 break;
793 }
794 /* Allow only single frame */
795 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
796 if (cfg.buffer_size != (FRAME_SIZE - 8))
797 rc = -EINVAL;
798 break;
799 } else {
800 if (cfg.buffer_size != (EVRC_FRAME_SIZE + 14))
801 rc = -EINVAL;
802 break;
803 }
804 audio->buffer_size = cfg.buffer_size;
805 break;
806 }
807 case AUDIO_GET_EVRC_ENC_CONFIG: {
808 if (copy_to_user((void *) arg, &audio->cfg, sizeof(audio->cfg)))
809 rc = -EFAULT;
810 break;
811 }
812 case AUDIO_SET_EVRC_ENC_CONFIG: {
813 struct msm_audio_evrc_enc_config cfg;
814 if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
815 rc = -EFAULT;
816 break;
817 }
818 MM_DBG("0X%8x, 0x%8x, 0x%8x\n", cfg.min_bit_rate,
819 cfg.max_bit_rate, cfg.cdma_rate);
820 if (cfg.min_bit_rate > CDMA_RATE_FULL || \
821 cfg.min_bit_rate < CDMA_RATE_EIGHTH) {
822 MM_ERR("invalid min bitrate\n");
823 rc = -EFAULT;
824 break;
825 }
826 if (cfg.max_bit_rate > CDMA_RATE_FULL || \
827 cfg.max_bit_rate < CDMA_RATE_EIGHTH) {
828 MM_ERR("invalid max bitrate\n");
829 rc = -EFAULT;
830 break;
831 }
832 /* Recording Does not support Erase and Blank */
833 if (cfg.cdma_rate > CDMA_RATE_FULL ||
834 cfg.cdma_rate < CDMA_RATE_EIGHTH) {
835 MM_ERR("invalid qcelp cdma rate\n");
836 rc = -EFAULT;
837 break;
838 }
839 memcpy(&audio->cfg, &cfg, sizeof(cfg));
840 break;
841 }
842 default:
843 rc = -EINVAL;
844 }
845 mutex_unlock(&audio->lock);
846 return rc;
847}
848
849static ssize_t audevrc_in_read(struct file *file,
850 char __user *buf,
851 size_t count, loff_t *pos)
852{
853 struct audio_evrc_in *audio = file->private_data;
854 unsigned long flags;
855 const char __user *start = buf;
856 void *data;
857 uint32_t index;
858 uint32_t size;
859 int rc = 0;
860 struct evrc_encoded_meta_out meta_field;
861 struct audio_frame_nt *nt_frame;
862 MM_DBG("count = %d\n", count);
863 mutex_lock(&audio->read_lock);
864 while (count > 0) {
865 rc = wait_event_interruptible(
866 audio->wait, (audio->in_count > 0) || audio->stopped ||
867 audio->rflush);
868 if (rc < 0)
869 break;
870
871 if (audio->rflush) {
872 rc = -EBUSY;
873 break;
874 }
875 if (audio->stopped && !audio->in_count) {
876 MM_DBG("Driver in stop state, No more buffer to read");
877 rc = 0;/* End of File */
878 break;
879 }
880
881 index = audio->in_tail;
882 data = (uint8_t *) audio->in[index].data;
883 size = audio->in[index].size;
884
885 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
886 nt_frame = (struct audio_frame_nt *)(data -
887 sizeof(struct audio_frame_nt));
888 memcpy((char *)&meta_field.time_stamp_dword_lsw,
889 (char *)&nt_frame->time_stamp_dword_lsw,
890 (sizeof(struct evrc_encoded_meta_out) - \
891 sizeof(uint16_t)));
892 meta_field.metadata_len =
893 sizeof(struct evrc_encoded_meta_out);
894 if (copy_to_user((char *)start, (char *)&meta_field,
895 sizeof(struct evrc_encoded_meta_out))) {
896 rc = -EFAULT;
897 break;
898 }
899 if (nt_frame->nflag_lsw & 0x0001) {
900 MM_ERR("recieved EOS in read call\n");
901 audio->eos_ack = 1;
902 }
903 buf += sizeof(struct evrc_encoded_meta_out);
904 count -= sizeof(struct evrc_encoded_meta_out);
905 }
906 if (count >= size) {
907 /* order the reads on the buffer */
908 dma_coherent_post_ops();
909 if (copy_to_user(buf, data, size)) {
910 rc = -EFAULT;
911 break;
912 }
913 spin_lock_irqsave(&audio->dsp_lock, flags);
914 if (index != audio->in_tail) {
915 /* overrun -- data is
916 * invalid and we need to retry */
917 spin_unlock_irqrestore(&audio->dsp_lock, flags);
918 continue;
919 }
920 audio->in[index].size = 0;
921 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
922 audio->in_count--;
923 spin_unlock_irqrestore(&audio->dsp_lock, flags);
924 count -= size;
925 buf += size;
926 if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)) {
927 if (!audio->eos_ack) {
928 MM_DBG("sending read ptr command \
929 %d %d\n",
930 audio->dsp_cnt,
931 audio->in_tail);
932 audevrc_in_dsp_read_buffer(audio,
933 audio->dsp_cnt++);
934 }
935 }
936 } else {
937 MM_ERR("short read\n");
938 break;
939 }
940 break;
941 }
942 mutex_unlock(&audio->read_lock);
943
944 if (buf > start)
945 return buf - start;
946
947 return rc;
948}
949
950static void audrec_pcm_send_data(struct audio_evrc_in *audio, unsigned needed)
951{
952 struct buffer *frame;
953 unsigned long flags;
954 MM_DBG("\n");
955 spin_lock_irqsave(&audio->dsp_lock, flags);
956 if (!audio->running)
957 goto done;
958
959 if (needed && !audio->wflush) {
960 /* We were called from the callback because the DSP
961 * requested more data. Note that the DSP does want
962 * more data, and if a buffer was in-flight, mark it
963 * as available (since the DSP must now be done with
964 * it).
965 */
966 audio->out_needed = 1;
967 frame = audio->out + audio->out_tail;
968 if (frame->used == 0xffffffff) {
969 MM_DBG("frame %d free\n", audio->out_tail);
970 frame->used = 0;
971 audio->out_tail ^= 1;
972 wake_up(&audio->write_wait);
973 }
974 }
975
976 if (audio->out_needed) {
977 /* If the DSP currently wants data and we have a
978 * buffer available, we will send it and reset
979 * the needed flag. We'll mark the buffer as in-flight
980 * so that it won't be recycled until the next buffer
981 * is requested
982 */
983
984 frame = audio->out + audio->out_tail;
985 if (frame->used) {
986 BUG_ON(frame->used == 0xffffffff);
987 audrec_pcm_buffer_ptr_refresh(audio,
988 audio->out_tail,
989 frame->used);
990 frame->used = 0xffffffff;
991 audio->out_needed = 0;
992 }
993 }
994 done:
995 spin_unlock_irqrestore(&audio->dsp_lock, flags);
996}
997
998static int audevrc_in_fsync(struct file *file, int datasync)
999
1000{
1001 struct audio_evrc_in *audio = file->private_data;
1002 int rc = 0;
1003
1004 MM_DBG("\n"); /* Macro prints the file name and function */
1005 if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) {
1006 rc = -EINVAL;
1007 goto done_nolock;
1008 }
1009
1010 mutex_lock(&audio->write_lock);
1011
1012 rc = wait_event_interruptible(audio->write_wait,
1013 audio->wflush);
1014 MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush);
1015
1016 if (rc < 0)
1017 goto done;
1018 else if (audio->wflush) {
1019 rc = -EBUSY;
1020 goto done;
1021 }
1022done:
1023 mutex_unlock(&audio->write_lock);
1024done_nolock:
1025 return rc;
1026
1027}
1028
1029int audrec_evrc_process_eos(struct audio_evrc_in *audio,
1030 const char __user *buf_start, unsigned short mfield_size)
1031{
1032 struct buffer *frame;
1033 int rc = 0;
1034
1035 frame = audio->out + audio->out_head;
1036
1037 rc = wait_event_interruptible(audio->write_wait,
1038 (audio->out_needed &&
1039 audio->out[0].used == 0 &&
1040 audio->out[1].used == 0)
1041 || (audio->stopped)
1042 || (audio->wflush));
1043
1044 if (rc < 0)
1045 goto done;
1046 if (audio->stopped || audio->wflush) {
1047 rc = -EBUSY;
1048 goto done;
1049 }
1050 if (copy_from_user(frame->data, buf_start, mfield_size)) {
1051 rc = -EFAULT;
1052 goto done;
1053 }
1054
1055 frame->mfield_sz = mfield_size;
1056 audio->out_head ^= 1;
1057 frame->used = mfield_size;
1058 MM_DBG("copying meta_out frame->used = %d\n", frame->used);
1059 audrec_pcm_send_data(audio, 0);
1060done:
1061 return rc;
1062}
1063
1064static ssize_t audevrc_in_write(struct file *file,
1065 const char __user *buf,
1066 size_t count, loff_t *pos)
1067{
1068 struct audio_evrc_in *audio = file->private_data;
1069 const char __user *start = buf;
1070 struct buffer *frame;
1071 char *cpy_ptr;
1072 int rc = 0, eos_condition = AUDPREPROC_EVRC_EOS_NONE;
1073 unsigned short mfield_size = 0;
1074 int write_count = 0;
1075 MM_DBG("cnt=%d\n", count);
1076
1077 if (count & 1)
1078 return -EINVAL;
1079
1080 if (audio->mode != MSM_AUD_ENC_MODE_NONTUNNEL)
1081 return -EINVAL;
1082
1083 mutex_lock(&audio->write_lock);
1084 frame = audio->out + audio->out_head;
1085 /* if supplied count is more than driver buffer size
1086 * then only copy driver buffer size
1087 */
1088 if (count > frame->size)
1089 count = frame->size;
1090
1091 write_count = count;
1092 cpy_ptr = frame->data;
1093 rc = wait_event_interruptible(audio->write_wait,
1094 (frame->used == 0)
1095 || (audio->stopped)
1096 || (audio->wflush));
1097 if (rc < 0)
1098 goto error;
1099
1100 if (audio->stopped || audio->wflush) {
1101 rc = -EBUSY;
1102 goto error;
1103 }
1104 if (audio->mfield) {
1105 if (buf == start) {
1106 /* Processing beginning of user buffer */
1107 if (__get_user(mfield_size,
1108 (unsigned short __user *) buf)) {
1109 rc = -EFAULT;
1110 goto error;
1111 } else if (mfield_size > count) {
1112 rc = -EINVAL;
1113 goto error;
1114 }
1115 MM_DBG("mf offset_val %x\n", mfield_size);
1116 if (copy_from_user(cpy_ptr, buf, mfield_size)) {
1117 rc = -EFAULT;
1118 goto error;
1119 }
1120 /* Check if EOS flag is set and buffer has
1121 * contains just meta field
1122 */
1123 if (cpy_ptr[AUDPREPROC_EVRC_EOS_FLG_OFFSET] &
1124 AUDPREPROC_EVRC_EOS_FLG_MASK) {
1125 eos_condition = AUDPREPROC_EVRC_EOS_SET;
1126 MM_DBG("EOS SET\n");
1127 if (mfield_size == count) {
1128 buf += mfield_size;
1129 eos_condition = 0;
1130 goto exit;
1131 } else
1132 cpy_ptr[AUDPREPROC_EVRC_EOS_FLG_OFFSET] &=
1133 ~AUDPREPROC_EVRC_EOS_FLG_MASK;
1134 }
1135 cpy_ptr += mfield_size;
1136 count -= mfield_size;
1137 buf += mfield_size;
1138 } else {
1139 mfield_size = 0;
1140 MM_DBG("continuous buffer\n");
1141 }
1142 frame->mfield_sz = mfield_size;
1143 }
1144 MM_DBG("copying the stream count = %d\n", count);
1145 if (copy_from_user(cpy_ptr, buf, count)) {
1146 rc = -EFAULT;
1147 goto error;
1148 }
1149exit:
1150 frame->used = count;
1151 audio->out_head ^= 1;
1152 if (!audio->flush_ack)
1153 audrec_pcm_send_data(audio, 0);
1154 else {
1155 audrec_pcm_send_data(audio, 1);
1156 audio->flush_ack = 0;
1157 }
1158 if (eos_condition == AUDPREPROC_EVRC_EOS_SET)
1159 rc = audrec_evrc_process_eos(audio, start, mfield_size);
1160 mutex_unlock(&audio->write_lock);
1161 return write_count;
1162error:
1163 mutex_unlock(&audio->write_lock);
1164 return rc;
1165}
1166
1167static int audevrc_in_release(struct inode *inode, struct file *file)
1168{
1169 struct audio_evrc_in *audio = file->private_data;
1170
1171 mutex_lock(&audio->lock);
1172 audevrc_in_disable(audio);
1173 audevrc_in_flush(audio);
1174 msm_adsp_put(audio->audrec);
1175
1176 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
1177 msm_adsp_put(audio->audpre);
1178
1179 audpreproc_aenc_free(audio->enc_id);
1180 audio->audrec = NULL;
1181 audio->audpre = NULL;
1182 audio->opened = 0;
1183 if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \
1184 (audio->out_data)) {
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301185 msm_subsystem_unmap_buffer(audio->map_v_write);
1186 free_contiguous_memory_by_paddr(audio->out_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001187 audio->out_data = NULL;
1188 }
1189 if (audio->data) {
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301190 msm_subsystem_unmap_buffer(audio->map_v_read);
1191 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001192 audio->data = NULL;
1193 }
1194 mutex_unlock(&audio->lock);
1195 return 0;
1196}
1197
1198static struct audio_evrc_in the_audio_evrc_in;
1199
1200static int audevrc_in_open(struct inode *inode, struct file *file)
1201{
1202 struct audio_evrc_in *audio = &the_audio_evrc_in;
1203 int rc;
1204 int encid;
1205 int dma_size = 0;
1206
1207 mutex_lock(&audio->lock);
1208 if (audio->opened) {
1209 rc = -EBUSY;
1210 goto done;
1211 }
1212 if ((file->f_mode & FMODE_WRITE) &&
1213 (file->f_mode & FMODE_READ)) {
1214 audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL;
1215 dma_size = NT_DMASZ;
1216 MM_DBG("Opened for non tunnel mode encoding\n");
1217 } else if (!(file->f_mode & FMODE_WRITE) &&
1218 (file->f_mode & FMODE_READ)) {
1219 audio->mode = MSM_AUD_ENC_MODE_TUNNEL;
1220 dma_size = DMASZ;
1221 MM_DBG("Opened for tunnel mode encoding\n");
1222 } else {
1223 MM_ERR("Invalid mode\n");
1224 rc = -EACCES;
1225 goto done;
1226 }
1227
1228 /* Settings will be re-config at AUDIO_SET_CONFIG,
1229 * but at least we need to have initial config
1230 */
1231 audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_8000,
1232 audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_8000;
1233 audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO;
1234 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)
1235 audio->buffer_size = (EVRC_FRAME_SIZE + 14);
1236 else
1237 audio->buffer_size = EVRC_FRAME_SIZE;
1238 audio->enc_type = AUDREC_CMD_TYPE_0_INDEX_EVRC | audio->mode;
1239
1240 audio->cfg.cdma_rate = CDMA_RATE_FULL;
1241 audio->cfg.min_bit_rate = CDMA_RATE_FULL;
1242 audio->cfg.max_bit_rate = CDMA_RATE_FULL;
1243
1244 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
1245 rc = audmgr_open(&audio->audmgr);
1246 if (rc)
1247 goto done;
1248 }
1249
1250 encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name,
1251 &audio->queue_ids);
1252 if (encid < 0) {
1253 MM_ERR("No free encoder available\n");
1254 rc = -ENODEV;
1255 goto done;
1256 }
1257 audio->enc_id = encid;
1258
1259 rc = msm_adsp_get(audio->module_name, &audio->audrec,
1260 &audrec_evrc_adsp_ops, audio);
1261 if (rc) {
1262 audpreproc_aenc_free(audio->enc_id);
1263 goto done;
1264 }
1265
1266 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
1267 rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
1268 &audpre_evrc_adsp_ops, audio);
1269 if (rc) {
1270 msm_adsp_put(audio->audrec);
1271 audpreproc_aenc_free(audio->enc_id);
1272 goto done;
1273 }
1274 }
1275
1276 audio->dsp_cnt = 0;
1277 audio->stopped = 0;
1278 audio->wflush = 0;
1279 audio->rflush = 0;
1280 audio->flush_ack = 0;
1281
1282 audevrc_in_flush(audio);
1283 audevrc_out_flush(audio);
1284
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301285 audio->phys = allocate_contiguous_ebi_nomap(dma_size, SZ_4K);
1286 if (!audio->phys) {
1287 MM_ERR("could not allocate physical read buffers\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001288 rc = -ENOMEM;
1289 goto evt_error;
1290 } else {
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301291 audio->map_v_read = msm_subsystem_map_buffer(
1292 audio->phys, dma_size,
1293 MSM_SUBSYSTEM_MAP_KADDR,
1294 NULL, 0);
1295 if (IS_ERR(audio->map_v_read)) {
1296 MM_ERR("could not map physical address\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001297 rc = -ENOMEM;
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301298 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001299 goto evt_error;
1300 }
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301301 audio->data = audio->map_v_read->vaddr;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001302 MM_DBG("read buf: phy addr 0x%08x kernel addr 0x%08x\n",
1303 audio->phys, (int)audio->data);
1304 }
1305 audio->out_data = NULL;
1306 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301307 audio->out_phys = allocate_contiguous_ebi_nomap(BUFFER_SIZE,
1308 SZ_4K);
1309 if (!audio->out_phys) {
1310 MM_ERR("could not allocate physical write buffers\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001311 rc = -ENOMEM;
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301312 msm_subsystem_unmap_buffer(audio->map_v_read);
1313 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001314 goto evt_error;
1315 } else {
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301316 audio->map_v_write = msm_subsystem_map_buffer(
1317 audio->out_phys, BUFFER_SIZE,
1318 MSM_SUBSYSTEM_MAP_KADDR,
1319 NULL, 0);
1320
1321 if (IS_ERR(audio->map_v_write)) {
1322 MM_ERR("could not map write phys address\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001323 rc = -ENOMEM;
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301324 msm_subsystem_unmap_buffer(audio->map_v_read);
1325 free_contiguous_memory_by_paddr(audio->phys);
1326 free_contiguous_memory_by_paddr(\
1327 audio->out_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001328 goto evt_error;
1329 }
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301330 audio->out_data = audio->map_v_write->vaddr;
1331 MM_DBG("wr buf: phy addr 0x%08x kernel addr 0x%08x\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001332 audio->out_phys, (int)audio->out_data);
1333 }
1334
1335 /* Initialize buffer */
1336 audio->out[0].data = audio->out_data + 0;
1337 audio->out[0].addr = audio->out_phys + 0;
1338 audio->out[0].size = OUT_BUFFER_SIZE;
1339
1340 audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE;
1341 audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE;
1342 audio->out[1].size = OUT_BUFFER_SIZE;
1343
1344 MM_DBG("audio->out[0].data = %d audio->out[1].data = %d",
1345 (unsigned int)audio->out[0].data,
1346 (unsigned int)audio->out[1].data);
1347 audio->mfield = NT_FRAME_HEADER_SIZE;
1348 audio->out_frame_cnt++;
1349 }
1350 file->private_data = audio;
1351 audio->opened = 1;
1352
1353done:
1354 mutex_unlock(&audio->lock);
1355 return rc;
1356evt_error:
1357 msm_adsp_put(audio->audrec);
1358 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
1359 msm_adsp_put(audio->audpre);
1360
1361 audpreproc_aenc_free(audio->enc_id);
1362 mutex_unlock(&audio->lock);
1363 return rc;
1364}
1365
1366static const struct file_operations audio_evrc_in_fops = {
1367 .owner = THIS_MODULE,
1368 .open = audevrc_in_open,
1369 .release = audevrc_in_release,
1370 .read = audevrc_in_read,
1371 .write = audevrc_in_write,
1372 .fsync = audevrc_in_fsync,
1373 .unlocked_ioctl = audevrc_in_ioctl,
1374};
1375
1376static struct miscdevice audevrc_in_misc = {
1377 .minor = MISC_DYNAMIC_MINOR,
1378 .name = "msm_evrc_in",
1379 .fops = &audio_evrc_in_fops,
1380};
1381
1382static int __init audevrc_in_init(void)
1383{
1384 mutex_init(&the_audio_evrc_in.lock);
1385 mutex_init(&the_audio_evrc_in.read_lock);
1386 spin_lock_init(&the_audio_evrc_in.dsp_lock);
1387 init_waitqueue_head(&the_audio_evrc_in.wait);
1388 init_waitqueue_head(&the_audio_evrc_in.wait_enable);
1389 mutex_init(&the_audio_evrc_in.write_lock);
1390 init_waitqueue_head(&the_audio_evrc_in.write_wait);
1391 return misc_register(&audevrc_in_misc);
1392}
1393device_initcall(audevrc_in_init);