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