blob: bfe48eeece2577d13a60ec504822cf5bcaf3667f [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 *
Manish Dewangana4f1df02012-02-08 17:06:54 +05305 * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Manish Dewangan95ae3572011-03-15 14:58:12 +05306 *
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 */
Manish Dewangan95ae3572011-03-15 14:58:12 +0530700 wake_up(&audio->wait);
701 mutex_lock(&audio->read_lock);
Manish Dewangana4f1df02012-02-08 17:06:54 +0530702 audaac_in_flush(audio);
Manish Dewangan95ae3572011-03-15 14:58:12 +0530703 mutex_unlock(&audio->read_lock);
Manish Dewangana4f1df02012-02-08 17:06:54 +0530704 wake_up(&audio->write_wait);
705 mutex_lock(&audio->write_lock);
706 audaac_out_flush(audio);
707 mutex_unlock(&audio->write_lock);
Manish Dewangan95ae3572011-03-15 14:58:12 +0530708}
709
710static void audaac_in_flush(struct audio_aac_in *audio)
711{
712 int i;
Manish Dewangana4f1df02012-02-08 17:06:54 +0530713 unsigned long flags;
Manish Dewangan95ae3572011-03-15 14:58:12 +0530714
715 audio->dsp_cnt = 0;
Manish Dewangana4f1df02012-02-08 17:06:54 +0530716 spin_lock_irqsave(&audio->dsp_lock, flags);
Manish Dewangan95ae3572011-03-15 14:58:12 +0530717 audio->in_head = 0;
718 audio->in_tail = 0;
719 audio->in_count = 0;
720 audio->eos_ack = 0;
721 for (i = FRAME_NUM-1; i >= 0; i--) {
722 audio->in[i].size = 0;
723 audio->in[i].read = 0;
724 }
Manish Dewangana4f1df02012-02-08 17:06:54 +0530725 spin_unlock_irqrestore(&audio->dsp_lock, flags);
Manish Dewangan95ae3572011-03-15 14:58:12 +0530726 MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes));
727 MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples));
728 atomic_set(&audio->in_bytes, 0);
729 atomic_set(&audio->in_samples, 0);
730}
731
732static void audaac_out_flush(struct audio_aac_in *audio)
733{
734 int i;
Manish Dewangana4f1df02012-02-08 17:06:54 +0530735 unsigned long flags;
Manish Dewangan95ae3572011-03-15 14:58:12 +0530736
737 audio->out_head = 0;
Manish Dewangan95ae3572011-03-15 14:58:12 +0530738 audio->out_count = 0;
Manish Dewangana4f1df02012-02-08 17:06:54 +0530739 spin_lock_irqsave(&audio->dsp_lock, flags);
740 audio->out_tail = 0;
Manish Dewangan95ae3572011-03-15 14:58:12 +0530741 for (i = OUT_FRAME_NUM-1; i >= 0; i--) {
742 audio->out[i].size = 0;
743 audio->out[i].read = 0;
744 audio->out[i].used = 0;
745 }
Manish Dewangana4f1df02012-02-08 17:06:54 +0530746 spin_unlock_irqrestore(&audio->dsp_lock, flags);
Manish Dewangan95ae3572011-03-15 14:58:12 +0530747}
748
749/* ------------------- device --------------------- */
750static long audaac_in_ioctl(struct file *file,
751 unsigned int cmd, unsigned long arg)
752{
753 struct audio_aac_in *audio = file->private_data;
754 int rc = 0;
755
756 MM_DBG("\n");
757 if (cmd == AUDIO_GET_STATS) {
758 struct msm_audio_stats stats;
759 stats.byte_count = atomic_read(&audio->in_bytes);
760 stats.sample_count = atomic_read(&audio->in_samples);
761 if (copy_to_user((void *) arg, &stats, sizeof(stats)))
762 return -EFAULT;
763 return rc;
764 }
765
766 mutex_lock(&audio->lock);
767 switch (cmd) {
768 case AUDIO_START: {
769 rc = audaac_in_enable(audio);
770 if (!rc) {
771 rc =
772 wait_event_interruptible_timeout(audio->wait_enable,
773 audio->running != 0, 1*HZ);
774 MM_DBG("state %d rc = %d\n", audio->running, rc);
775
776 if (audio->running == 0)
777 rc = -ENODEV;
778 else
779 rc = 0;
780 }
781 audio->stopped = 0;
782 break;
783 }
784 case AUDIO_STOP: {
785 rc = audaac_in_disable(audio);
786 audio->stopped = 1;
787 break;
788 }
789 case AUDIO_FLUSH: {
790 MM_DBG("AUDIO_FLUSH\n");
791 audio->rflush = 1;
792 audio->wflush = 1;
793 audaac_ioport_reset(audio);
794 if (audio->running) {
795 audaac_flush_command(audio);
796 rc = wait_event_interruptible(audio->write_wait,
797 !audio->wflush);
798 if (rc < 0) {
799 MM_ERR("AUDIO_FLUSH interrupted\n");
800 rc = -EINTR;
801 }
802 } else {
803 audio->rflush = 0;
804 audio->wflush = 0;
805 }
806 break;
807 }
808 case AUDIO_GET_CONFIG: {
809 struct msm_audio_config cfg;
810 memset(&cfg, 0, sizeof(cfg));
811 cfg.buffer_size = OUT_BUFFER_SIZE;
812 cfg.buffer_count = OUT_FRAME_NUM;
813 cfg.sample_rate = convert_samp_index(audio->samp_rate);
814 cfg.channel_count = 1;
815 cfg.type = 0;
816 cfg.unused[0] = 0;
817 cfg.unused[1] = 0;
818 cfg.unused[2] = 0;
819 if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
820 rc = -EFAULT;
821 else
822 rc = 0;
823 break;
824 }
825 case AUDIO_GET_STREAM_CONFIG: {
826 struct msm_audio_stream_config cfg;
827 memset(&cfg, 0, sizeof(cfg));
828 cfg.buffer_size = audio->buffer_size;
829 cfg.buffer_count = FRAME_NUM;
830 if (copy_to_user((void *)arg, &cfg, sizeof(cfg)))
831 rc = -EFAULT;
832 else
833 rc = 0;
834 break;
835 }
836 case AUDIO_SET_STREAM_CONFIG: {
837 struct msm_audio_stream_config cfg;
838 if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
839 rc = -EFAULT;
840 break;
841 }
842 /* Allow only single frame */
843 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
844 if (cfg.buffer_size != (FRAME_SIZE - 8))
845 rc = -EINVAL;
846 break;
847 } else {
848 if (cfg.buffer_size != (AAC_FRAME_SIZE + 14))
849 rc = -EINVAL;
850 break;
851 }
852 audio->buffer_size = cfg.buffer_size;
853 break;
854 }
855 case AUDIO_GET_AAC_ENC_CONFIG: {
856 struct msm_audio_aac_enc_config cfg;
857 if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO)
858 cfg.channels = 1;
859 else
860 cfg.channels = 2;
861 cfg.sample_rate = convert_samp_index(audio->samp_rate);
862 cfg.bit_rate = audio->bit_rate;
863 cfg.stream_format = AUDIO_AAC_FORMAT_RAW;
864 if (copy_to_user((void *)arg, &cfg, sizeof(cfg)))
865 rc = -EFAULT;
866 break;
867 }
868 case AUDIO_SET_AAC_ENC_CONFIG: {
869 struct msm_audio_aac_enc_config cfg;
870 unsigned int record_quality;
871 if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
872 rc = -EFAULT;
873 break;
874 }
875 if (cfg.stream_format != AUDIO_AAC_FORMAT_RAW) {
876 MM_ERR("unsupported AAC format\n");
877 rc = -EINVAL;
878 break;
879 }
880 record_quality = bitrate_to_record_quality(cfg.sample_rate,
881 cfg.channels, cfg.bit_rate);
882 /* Range of Record Quality Supported by DSP, Q12 format */
883 if ((record_quality < 0x800) || (record_quality > 0x4000)) {
884 MM_ERR("Unsupported bit rate\n");
885 rc = -EINVAL;
886 break;
887 }
888 MM_DBG("channels = %d\n", cfg.channels);
889 if (cfg.channels == 1) {
890 cfg.channels = AUDREC_CMD_STEREO_MODE_MONO;
891 } else if (cfg.channels == 2) {
892 cfg.channels = AUDREC_CMD_STEREO_MODE_STEREO;
893 } else {
894 rc = -EINVAL;
895 break;
896 }
897
898 audio->samp_rate = convert_samp_rate(cfg.sample_rate);
899 audio->samp_rate_index =
900 convert_dsp_samp_index(cfg.sample_rate);
901 audio->channel_mode = cfg.channels;
902 audio->bit_rate = cfg.bit_rate;
903 audio->record_quality = record_quality;
904 MM_DBG(" Record Quality = 0x%8x\n", audio->record_quality);
905 break;
906 }
907
908 default:
909 rc = -EINVAL;
910 }
911 mutex_unlock(&audio->lock);
912 return rc;
913}
914
915static ssize_t audaac_in_read(struct file *file,
916 char __user *buf,
917 size_t count, loff_t *pos)
918{
919 struct audio_aac_in *audio = file->private_data;
920 unsigned long flags;
921 const char __user *start = buf;
922 void *data;
923 uint32_t index;
924 uint32_t size;
925 int rc = 0;
926 struct aac_encoded_meta_out meta_field;
927 struct audio_frame_nt *nt_frame;
928 MM_DBG("count = %d\n", count);
929 mutex_lock(&audio->read_lock);
930 while (count > 0) {
931 rc = wait_event_interruptible(
932 audio->wait, (audio->in_count > 0) || audio->stopped ||
933 audio->rflush);
934 if (rc < 0)
935 break;
936
937 if (audio->rflush) {
938 rc = -EBUSY;
939 break;
940 }
941 if (audio->stopped && !audio->in_count) {
942 MM_DBG("Driver in stop state, No more buffer to read");
943 rc = 0;/* End of File */
944 break;
945 }
946
947 index = audio->in_tail;
948 data = (uint8_t *) audio->in[index].data;
949 size = audio->in[index].size;
950
951 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
952 nt_frame = (struct audio_frame_nt *)(data -
953 sizeof(struct audio_frame_nt));
954 memcpy((char *)&meta_field.time_stamp_dword_lsw,
955 (char *)&nt_frame->time_stamp_dword_lsw,
956 (sizeof(struct aac_encoded_meta_out) - \
957 sizeof(uint16_t)));
958 meta_field.metadata_len =
959 sizeof(struct aac_encoded_meta_out);
960 if (copy_to_user((char *)start, (char *)&meta_field,
961 sizeof(struct aac_encoded_meta_out))) {
962 rc = -EFAULT;
963 break;
964 }
965 if (nt_frame->nflag_lsw & 0x0001) {
966 MM_DBG("recieved EOS in read call\n");
967 audio->eos_ack = 1;
968 }
969 buf += sizeof(struct aac_encoded_meta_out);
970 count -= sizeof(struct aac_encoded_meta_out);
971 }
972 if (count >= size) {
973 /* order the reads on the buffer */
974 dma_coherent_post_ops();
975 if (copy_to_user(buf, data, size)) {
976 rc = -EFAULT;
977 break;
978 }
979 spin_lock_irqsave(&audio->dsp_lock, flags);
980 if (index != audio->in_tail) {
981 /* overrun -- data is
982 * invalid and we need to retry */
983 spin_unlock_irqrestore(&audio->dsp_lock, flags);
984 continue;
985 }
986 audio->in[index].size = 0;
987 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
988 audio->in_count--;
989 spin_unlock_irqrestore(&audio->dsp_lock, flags);
990 count -= size;
991 buf += size;
992 if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)) {
993 if (!audio->eos_ack) {
994 MM_DBG("sending read ptr command \
995 %d %d\n",
996 audio->dsp_cnt,
997 audio->in_tail);
998 audaac_in_dsp_read_buffer(audio,
999 audio->dsp_cnt++);
1000 }
1001 }
1002 } else {
1003 MM_ERR("short read\n");
1004 break;
1005 }
1006 break;
1007 }
1008 mutex_unlock(&audio->read_lock);
1009
1010 if (buf > start)
1011 return buf - start;
1012
1013 return rc;
1014}
1015
1016static void audrec_pcm_send_data(struct audio_aac_in *audio, unsigned needed)
1017{
1018 struct buffer *frame;
1019 unsigned long flags;
1020 MM_DBG("\n");
1021 spin_lock_irqsave(&audio->dsp_lock, flags);
1022 if (!audio->running)
1023 goto done;
1024
1025 if (needed && !audio->wflush) {
1026 /* We were called from the callback because the DSP
1027 * requested more data. Note that the DSP does want
1028 * more data, and if a buffer was in-flight, mark it
1029 * as available (since the DSP must now be done with
1030 * it).
1031 */
1032 audio->out_needed = 1;
1033 frame = audio->out + audio->out_tail;
1034 if (frame->used == 0xffffffff) {
1035 MM_DBG("frame %d free\n", audio->out_tail);
1036 frame->used = 0;
1037 audio->out_tail ^= 1;
1038 wake_up(&audio->write_wait);
1039 }
1040 }
1041
1042 if (audio->out_needed) {
1043 /* If the DSP currently wants data and we have a
1044 * buffer available, we will send it and reset
1045 * the needed flag. We'll mark the buffer as in-flight
1046 * so that it won't be recycled until the next buffer
1047 * is requested
1048 */
1049
1050 frame = audio->out + audio->out_tail;
1051 if (frame->used) {
1052 BUG_ON(frame->used == 0xffffffff);
1053 audrec_pcm_buffer_ptr_refresh(audio,
1054 audio->out_tail,
1055 frame->used);
1056 frame->used = 0xffffffff;
1057 audio->out_needed = 0;
1058 }
1059 }
1060 done:
1061 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1062}
1063
1064
1065static int audaac_in_fsync(struct file *file, int datasync)
1066
1067{
1068 struct audio_aac_in *audio = file->private_data;
1069 int rc = 0;
1070
1071 MM_DBG("\n"); /* Macro prints the file name and function */
1072 if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) {
1073 rc = -EINVAL;
1074 goto done_nolock;
1075 }
1076
1077 mutex_lock(&audio->write_lock);
1078
1079 rc = wait_event_interruptible(audio->write_wait,
1080 audio->wflush);
1081 MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush);
1082
1083 if (rc < 0)
1084 goto done;
1085 else if (audio->wflush) {
1086 rc = -EBUSY;
1087 goto done;
1088 }
1089done:
1090 mutex_unlock(&audio->write_lock);
1091done_nolock:
1092 return rc;
1093
1094}
1095
1096int audrec_aac_process_eos(struct audio_aac_in *audio,
1097 const char __user *buf_start, unsigned short mfield_size)
1098{
1099 struct buffer *frame;
1100 int rc = 0;
1101
1102 frame = audio->out + audio->out_head;
1103
1104 rc = wait_event_interruptible(audio->write_wait,
1105 (audio->out_needed &&
1106 audio->out[0].used == 0 &&
1107 audio->out[1].used == 0)
1108 || (audio->stopped)
1109 || (audio->wflush));
1110
1111 if (rc < 0)
1112 goto done;
1113 if (audio->stopped || audio->wflush) {
1114 rc = -EBUSY;
1115 goto done;
1116 }
1117 if (copy_from_user(frame->data, buf_start, mfield_size)) {
1118 rc = -EFAULT;
1119 goto done;
1120 }
1121
1122 frame->mfield_sz = mfield_size;
1123 audio->out_head ^= 1;
1124 frame->used = mfield_size;
1125 MM_DBG("copying meta_out frame->used = %d\n", frame->used);
1126 audrec_pcm_send_data(audio, 0);
1127done:
1128 return rc;
1129}
1130static ssize_t audaac_in_write(struct file *file,
1131 const char __user *buf,
1132 size_t count, loff_t *pos)
1133{
1134 struct audio_aac_in *audio = file->private_data;
1135 const char __user *start = buf;
1136 struct buffer *frame;
1137 char *cpy_ptr;
1138 int rc = 0, eos_condition = AUDPREPROC_AAC_EOS_NONE;
1139 unsigned short mfield_size = 0;
1140 int write_count = 0;
1141 MM_DBG("cnt=%d\n", count);
1142
1143 if (count & 1)
1144 return -EINVAL;
1145
1146 if (audio->mode != MSM_AUD_ENC_MODE_NONTUNNEL)
1147 return -EINVAL;
1148
1149 mutex_lock(&audio->write_lock);
1150 frame = audio->out + audio->out_head;
1151 /* if supplied count is more than driver buffer size
1152 * then only copy driver buffer size
1153 */
1154 if (count > frame->size)
1155 count = frame->size;
1156
1157 write_count = count;
1158 cpy_ptr = frame->data;
1159 rc = wait_event_interruptible(audio->write_wait,
1160 (frame->used == 0)
1161 || (audio->stopped)
1162 || (audio->wflush));
1163 if (rc < 0)
1164 goto error;
1165
1166 if (audio->stopped || audio->wflush) {
1167 rc = -EBUSY;
1168 goto error;
1169 }
1170 if (audio->mfield) {
1171 if (buf == start) {
1172 /* Processing beginning of user buffer */
1173 if (__get_user(mfield_size,
1174 (unsigned short __user *) buf)) {
1175 rc = -EFAULT;
1176 goto error;
1177 } else if (mfield_size > count) {
1178 rc = -EINVAL;
1179 goto error;
1180 }
1181 MM_DBG("mf offset_val %x\n", mfield_size);
1182 if (copy_from_user(cpy_ptr, buf, mfield_size)) {
1183 rc = -EFAULT;
1184 goto error;
1185 }
1186 /* Check if EOS flag is set and buffer has
1187 * contains just meta field
1188 */
1189 if (cpy_ptr[AUDPREPROC_AAC_EOS_FLG_OFFSET] &
1190 AUDPREPROC_AAC_EOS_FLG_MASK) {
1191 eos_condition = AUDPREPROC_AAC_EOS_SET;
1192 MM_DBG("EOS SET\n");
1193 if (mfield_size == count) {
1194 buf += mfield_size;
1195 eos_condition = 0;
1196 goto exit;
1197 } else
1198 cpy_ptr[AUDPREPROC_AAC_EOS_FLG_OFFSET] &=
1199 ~AUDPREPROC_AAC_EOS_FLG_MASK;
1200 }
1201 cpy_ptr += mfield_size;
1202 count -= mfield_size;
1203 buf += mfield_size;
1204 } else {
1205 mfield_size = 0;
1206 MM_DBG("continuous buffer\n");
1207 }
1208 frame->mfield_sz = mfield_size;
1209 }
1210 MM_DBG("copying the stream count = %d\n", count);
1211 if (copy_from_user(cpy_ptr, buf, count)) {
1212 rc = -EFAULT;
1213 goto error;
1214 }
1215exit:
1216 frame->used = count;
1217 audio->out_head ^= 1;
1218 if (!audio->flush_ack)
1219 audrec_pcm_send_data(audio, 0);
1220 else {
1221 audrec_pcm_send_data(audio, 1);
1222 audio->flush_ack = 0;
1223 }
1224 if (eos_condition == AUDPREPROC_AAC_EOS_SET)
1225 rc = audrec_aac_process_eos(audio, start, mfield_size);
1226 mutex_unlock(&audio->write_lock);
1227 return write_count;
1228error:
1229 mutex_unlock(&audio->write_lock);
1230 return rc;
1231}
1232
1233static int audaac_in_release(struct inode *inode, struct file *file)
1234{
1235 struct audio_aac_in *audio = file->private_data;
1236
1237 mutex_lock(&audio->lock);
1238 audaac_in_disable(audio);
1239 audaac_in_flush(audio);
1240 msm_adsp_put(audio->audrec);
1241
1242 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
1243 msm_adsp_put(audio->audpre);
1244
1245 audpreproc_aenc_free(audio->enc_id);
1246 audio->audrec = NULL;
1247 audio->audpre = NULL;
1248 audio->opened = 0;
1249
1250 if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \
1251 (audio->out_data)) {
Manish Dewangan95ae3572011-03-15 14:58:12 +05301252 msm_subsystem_unmap_buffer(audio->map_v_write);
1253 free_contiguous_memory_by_paddr(audio->out_phys);
1254 audio->out_data = NULL;
1255 }
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301256
1257 if (audio->data) {
1258 msm_subsystem_unmap_buffer(audio->map_v_read);
1259 free_contiguous_memory_by_paddr(audio->phys);
1260 audio->data = NULL;
1261 }
Manish Dewangan95ae3572011-03-15 14:58:12 +05301262 mutex_unlock(&audio->lock);
1263 return 0;
1264}
1265
1266struct audio_aac_in the_audio_aac_in;
1267
1268static int audaac_in_open(struct inode *inode, struct file *file)
1269{
1270 struct audio_aac_in *audio = &the_audio_aac_in;
1271 int rc;
1272 int encid;
1273 int dma_size = 0;
1274
1275 mutex_lock(&audio->lock);
1276 if (audio->opened) {
1277 rc = -EBUSY;
1278 goto done;
1279 }
1280 if ((file->f_mode & FMODE_WRITE) &&
1281 (file->f_mode & FMODE_READ)) {
1282 audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL;
1283 dma_size = NT_DMASZ;
1284 MM_DBG("Opened for non tunnel mode encoding\n");
1285 } else if (!(file->f_mode & FMODE_WRITE) &&
1286 (file->f_mode & FMODE_READ)) {
1287 audio->mode = MSM_AUD_ENC_MODE_TUNNEL;
1288 dma_size = DMASZ;
1289 MM_DBG("Opened for tunnel mode encoding\n");
1290 } else {
1291 MM_ERR("Invalid mode\n");
1292 rc = -EACCES;
1293 goto done;
1294 }
1295
1296 /* Settings will be re-config at AUDIO_SET_CONFIG,
1297 * but at least we need to have initial config
1298 */
1299 audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025;
1300 audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025;
1301
1302 /* For AAC, bit rate hard coded, default settings is
1303 * sample rate (11025) x channel count (1) x recording quality (1.75)
1304 * = 19293 bps */
1305 audio->bit_rate = 19293;
1306 audio->record_quality = 0x1c00;
1307
1308 audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO;
1309 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)
1310 audio->buffer_size = (AAC_FRAME_SIZE + 14);
1311 else
1312 audio->buffer_size = (FRAME_SIZE - 8);
1313 audio->enc_type = AUDREC_CMD_TYPE_0_INDEX_AAC | audio->mode;
1314
1315 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
1316 rc = audmgr_open(&audio->audmgr);
1317 if (rc)
1318 goto done;
1319 }
1320
1321 encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name,
1322 &audio->queue_ids);
1323 if (encid < 0) {
1324 MM_ERR("No free encoder available\n");
1325 rc = -ENODEV;
1326 goto done;
1327 }
1328 audio->enc_id = encid;
1329
1330 rc = msm_adsp_get(audio->module_name, &audio->audrec,
1331 &audrec_aac_adsp_ops, audio);
1332 if (rc) {
1333 audpreproc_aenc_free(audio->enc_id);
1334 goto done;
1335 }
1336
1337 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
1338 rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
1339 &audpre_aac_adsp_ops, audio);
1340 if (rc) {
1341 msm_adsp_put(audio->audrec);
1342 audpreproc_aenc_free(audio->enc_id);
1343 goto done;
1344 }
1345 }
1346
1347 audio->dsp_cnt = 0;
1348 audio->stopped = 0;
1349 audio->wflush = 0;
1350 audio->rflush = 0;
1351 audio->flush_ack = 0;
1352
1353 audaac_in_flush(audio);
1354 audaac_out_flush(audio);
1355
1356 audio->phys = allocate_contiguous_ebi_nomap(dma_size, SZ_4K);
1357 if (audio->phys) {
1358 audio->map_v_read = msm_subsystem_map_buffer(
1359 audio->phys, dma_size,
1360 MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
1361 if (IS_ERR(audio->map_v_read)) {
1362 MM_ERR("could not map DMA buffers\n");
1363 rc = -ENOMEM;
1364 free_contiguous_memory_by_paddr(audio->phys);
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301365 goto evt_error;
Manish Dewangan95ae3572011-03-15 14:58:12 +05301366 }
1367 audio->data = audio->map_v_read->vaddr;
1368 } else {
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301369 MM_ERR("could not allocate read buffers\n");
Manish Dewangan95ae3572011-03-15 14:58:12 +05301370 rc = -ENOMEM;
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301371 goto evt_error;
Manish Dewangan95ae3572011-03-15 14:58:12 +05301372 }
1373 MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x\n",\
1374 (int) audio->data, (int) audio->phys);
1375
1376 audio->out_data = NULL;
1377 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
1378 audio->out_phys = allocate_contiguous_ebi_nomap(BUFFER_SIZE,
1379 SZ_4K);
1380 if (!audio->out_phys) {
1381 MM_ERR("could not allocate write buffers\n");
1382 rc = -ENOMEM;
1383 msm_subsystem_unmap_buffer(audio->map_v_read);
1384 free_contiguous_memory_by_paddr(audio->phys);
1385 goto evt_error;
1386 } else {
1387 audio->map_v_write = msm_subsystem_map_buffer(
1388 audio->out_phys, BUFFER_SIZE,
1389 MSM_SUBSYSTEM_MAP_KADDR, NULL, 0);
1390 if (IS_ERR(audio->map_v_write)) {
1391 MM_ERR("could not map write phys address\n");
1392 rc = -ENOMEM;
1393 msm_subsystem_unmap_buffer(audio->map_v_read);
1394 free_contiguous_memory_by_paddr(audio->phys);
1395 free_contiguous_memory_by_paddr(\
1396 audio->out_phys);
1397 goto evt_error;
1398 }
1399 audio->out_data = audio->map_v_write->vaddr;
1400 MM_DBG("wr buf: phy addr 0x%08x kernel addr 0x%08x\n",
1401 audio->out_phys, (int)audio->out_data);
1402 }
1403
1404 /* Initialize buffer */
1405 audio->out[0].data = audio->out_data + 0;
1406 audio->out[0].addr = audio->out_phys + 0;
1407 audio->out[0].size = OUT_BUFFER_SIZE;
1408
1409 audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE;
1410 audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE;
1411 audio->out[1].size = OUT_BUFFER_SIZE;
1412
1413 MM_DBG("audio->out[0].data = %d audio->out[1].data = %d",
1414 (unsigned int)audio->out[0].data,
1415 (unsigned int)audio->out[1].data);
1416 audio->mfield = NT_FRAME_HEADER_SIZE;
1417 audio->out_frame_cnt++;
1418 }
1419 file->private_data = audio;
1420 audio->opened = 1;
1421
1422done:
1423 mutex_unlock(&audio->lock);
1424 return rc;
1425evt_error:
1426 msm_adsp_put(audio->audrec);
1427 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
1428 msm_adsp_put(audio->audpre);
1429
1430 audpreproc_aenc_free(audio->enc_id);
1431 mutex_unlock(&audio->lock);
1432 return rc;
1433}
1434
1435static const struct file_operations audio_aac_in_fops = {
1436 .owner = THIS_MODULE,
1437 .open = audaac_in_open,
1438 .release = audaac_in_release,
1439 .read = audaac_in_read,
1440 .write = audaac_in_write,
1441 .fsync = audaac_in_fsync,
1442 .unlocked_ioctl = audaac_in_ioctl,
1443};
1444
1445static struct miscdevice audaac_in_misc = {
1446 .minor = MISC_DYNAMIC_MINOR,
1447 .name = "msm_aac_in",
1448 .fops = &audio_aac_in_fops,
1449};
1450
1451static int __init audaac_in_init(void)
1452{
1453 mutex_init(&the_audio_aac_in.lock);
1454 mutex_init(&the_audio_aac_in.read_lock);
1455 spin_lock_init(&the_audio_aac_in.dsp_lock);
1456 init_waitqueue_head(&the_audio_aac_in.wait);
1457 init_waitqueue_head(&the_audio_aac_in.wait_enable);
1458 mutex_init(&the_audio_aac_in.write_lock);
1459 init_waitqueue_head(&the_audio_aac_in.write_wait);
1460 return misc_register(&audaac_in_misc);
1461}
1462device_initcall(audaac_in_init);