blob: ab9f15c9cd1f0290ea2c8e0268edeb3e2acc3fd0 [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>
Manish Dewangan95ae3572011-03-15 14:58:12 +053043#include <mach/iommu_domains.h>
44
45#include <mach/msm_adsp.h>
46#include <mach/qdsp5/qdsp5audpreproc.h>
47#include <mach/qdsp5/qdsp5audpreproccmdi.h>
48#include <mach/qdsp5/qdsp5audpreprocmsg.h>
49#include <mach/qdsp5/qdsp5audreccmdi.h>
50#include <mach/qdsp5/qdsp5audrecmsg.h>
51#include <mach/debug_mm.h>
52
53#define FRAME_HEADER_SIZE 8 /* 8 bytes frame header */
54#define NT_FRAME_HEADER_SIZE 24 /* 24 bytes frame header */
55/* FRAME_NUM must be a power of two */
56#define FRAME_NUM 8
57#define AAC_FRAME_SIZE 1536 /* 36 bytes data */
58/*Tunnel mode : 1536 bytes data + 8 byte header*/
59#define FRAME_SIZE (AAC_FRAME_SIZE + FRAME_HEADER_SIZE)
60/* 1536 bytes data + 24 meta field*/
61#define NT_FRAME_SIZE (AAC_FRAME_SIZE + NT_FRAME_HEADER_SIZE)
62#define DMASZ (FRAME_SIZE * FRAME_NUM)
63#define NT_DMASZ (NT_FRAME_SIZE * FRAME_NUM)
64#define OUT_FRAME_NUM 2
65#define OUT_BUFFER_SIZE (32 * 1024 + NT_FRAME_HEADER_SIZE)
66#define BUFFER_SIZE (OUT_BUFFER_SIZE * OUT_FRAME_NUM)
67
68#define AUDPREPROC_AAC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer*/
69#define AUDPREPROC_AAC_EOS_FLG_MASK 0x01
70#define AUDPREPROC_AAC_EOS_NONE 0x0 /* No EOS detected */
71#define AUDPREPROC_AAC_EOS_SET 0x1 /* EOS set in meta field */
72
73struct buffer {
74 void *data;
75 uint32_t size;
76 uint32_t read;
77 uint32_t addr;
78 uint32_t used;
79 uint32_t mfield_sz;
80};
81
82struct audio_aac_in {
83 struct buffer in[FRAME_NUM];
84
85 spinlock_t dsp_lock;
86
87 atomic_t in_bytes;
88 atomic_t in_samples;
89
90 struct mutex lock;
91 struct mutex read_lock;
92 wait_queue_head_t wait;
93 wait_queue_head_t wait_enable;
94 /*write section*/
95 struct buffer out[OUT_FRAME_NUM];
96
97 uint8_t out_head;
98 uint8_t out_tail;
99 uint8_t out_needed; /* number of buffers the dsp is waiting for */
100 uint32_t out_count;
101
102 struct mutex write_lock;
103 wait_queue_head_t write_wait;
104 int32_t out_phys; /* physical address of write buffer */
105 char *out_data;
106 int mfield; /* meta field embedded in data */
107 int wflush; /*write flush */
108 int rflush; /*read flush*/
109 int out_frame_cnt;
110
111 struct msm_adsp_module *audrec;
112 struct msm_adsp_module *audpre;
113
114
115 /* configuration to use on next enable */
116 uint32_t samp_rate;
117 uint32_t channel_mode;
118 uint32_t buffer_size; /* Frame size (1536 bytes) */
119 uint32_t bit_rate; /* bit rate for AAC */
120 uint32_t record_quality; /* record quality (bits/sample/channel) */
121 uint32_t enc_type; /* 1 for AAC */
122 uint32_t mode; /* T or NT Mode*/
123 uint32_t dsp_cnt;
124 uint32_t in_head; /* next buffer dsp will write */
125 uint32_t in_tail; /* next buffer read() will read */
126 uint32_t in_count; /* number of buffers available to read() */
127
128 uint32_t eos_ack;
129 uint32_t flush_ack;
130
131 const char *module_name;
132 unsigned queue_ids;
133 uint16_t enc_id; /* Session Id */
134
135 unsigned short samp_rate_index;
136 uint32_t audrec_obj_idx ;
137
138 struct audmgr audmgr;
139
140 /* data allocated for various buffers */
141 char *data;
142 dma_addr_t phys;
Laura Abbott35111d32012-04-27 18:41:48 -0700143 void *map_v_read;
144 void *map_v_write;
Manish Dewangan95ae3572011-03-15 14:58:12 +0530145
146 int opened;
147 int enabled;
148 int running;
149 int stopped; /* set when stopped, cleared on flush */
150};
151
152struct audio_frame {
153 uint16_t frame_count_lsw;
154 uint16_t frame_count_msw;
155 uint16_t frame_length;
156 uint16_t erased_pcm;
157 unsigned char raw_bitstream[];
158} __packed;
159
160struct audio_frame_nt {
161 uint16_t metadata_len;
162 uint16_t frame_count_lsw;
163 uint16_t frame_count_msw;
164 uint16_t frame_length;
165 uint16_t erased_pcm;
166 uint16_t reserved;
167 uint16_t time_stamp_dword_lsw;
168 uint16_t time_stamp_dword_msw;
169 uint16_t time_stamp_lsw;
170 uint16_t time_stamp_msw;
171 uint16_t nflag_lsw;
172 uint16_t nflag_msw;
173 unsigned char raw_bitstream[]; /* samples */
174} __packed;
175
176struct aac_encoded_meta_out {
177 uint16_t metadata_len;
178 uint16_t time_stamp_dword_lsw;
179 uint16_t time_stamp_dword_msw;
180 uint16_t time_stamp_lsw;
181 uint16_t time_stamp_msw;
182 uint16_t nflag_lsw;
183 uint16_t nflag_msw;
184};
185
186/* Audrec Queue command sent macro's */
187#define audio_send_queue_pre(audio, cmd, len) \
188 msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len)
189
190#define audio_send_queue_recbs(audio, cmd, len) \
191 msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\
192 cmd, len)
193#define audio_send_queue_rec(audio, cmd, len) \
194 msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\
195 cmd, len)
196
197static int audaac_in_dsp_enable(struct audio_aac_in *audio, int enable);
198static int audaac_in_encparam_config(struct audio_aac_in *audio);
199static int audaac_in_encmem_config(struct audio_aac_in *audio);
200static int audaac_in_dsp_read_buffer(struct audio_aac_in *audio,
201 uint32_t read_cnt);
202static void audaac_in_flush(struct audio_aac_in *audio);
203
204static void audaac_in_get_dsp_frames(struct audio_aac_in *audio);
205static int audpcm_config(struct audio_aac_in *audio);
206static void audaac_out_flush(struct audio_aac_in *audio);
207static int audaac_in_routing_mode_config(struct audio_aac_in *audio);
208static void audrec_pcm_send_data(struct audio_aac_in *audio, unsigned needed);
209static void audaac_nt_in_get_dsp_frames(struct audio_aac_in *audio);
210static void audaac_in_flush(struct audio_aac_in *audio);
211
212static unsigned convert_dsp_samp_index(unsigned index)
213{
214 switch (index) {
215 case 48000: return AUDREC_CMD_SAMP_RATE_INDX_48000;
216 case 44100: return AUDREC_CMD_SAMP_RATE_INDX_44100;
217 case 32000: return AUDREC_CMD_SAMP_RATE_INDX_32000;
218 case 24000: return AUDREC_CMD_SAMP_RATE_INDX_24000;
219 case 22050: return AUDREC_CMD_SAMP_RATE_INDX_22050;
220 case 16000: return AUDREC_CMD_SAMP_RATE_INDX_16000;
221 case 12000: return AUDREC_CMD_SAMP_RATE_INDX_12000;
222 case 11025: return AUDREC_CMD_SAMP_RATE_INDX_11025;
223 case 8000: return AUDREC_CMD_SAMP_RATE_INDX_8000;
224 default: return AUDREC_CMD_SAMP_RATE_INDX_11025;
225 }
226}
227
228static unsigned convert_samp_rate(unsigned hz)
229{
230 switch (hz) {
231 case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000;
232 case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100;
233 case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000;
234 case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000;
235 case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050;
236 case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000;
237 case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000;
238 case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025;
239 case 8000: return RPC_AUD_DEF_SAMPLE_RATE_8000;
240 default: return RPC_AUD_DEF_SAMPLE_RATE_11025;
241 }
242}
243
244static unsigned convert_samp_index(unsigned index)
245{
246 switch (index) {
247 case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000;
248 case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100;
249 case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000;
250 case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000;
251 case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050;
252 case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000;
253 case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000;
254 case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025;
255 case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000;
256 default: return 11025;
257 }
258}
259
260/* Convert Bit Rate to Record Quality field of DSP */
261static unsigned int bitrate_to_record_quality(unsigned int sample_rate,
262 unsigned int channel, unsigned int bit_rate) {
263 unsigned int temp;
264
265 temp = sample_rate * channel;
266 MM_DBG(" sample rate * channel = %d\n", temp);
267 /* To represent in Q12 fixed format */
268 temp = (bit_rate * 4096) / temp;
269 MM_DBG(" Record Quality = 0x%8x\n", temp);
270 return temp;
271}
272
273/* must be called with audio->lock held */
274static int audaac_in_enable(struct audio_aac_in *audio)
275{
276 struct audmgr_config cfg;
277 int rc;
278
279 if (audio->enabled)
280 return 0;
281
282 cfg.tx_rate = audio->samp_rate;
283 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
284 cfg.def_method = RPC_AUD_DEF_METHOD_RECORD;
285 cfg.codec = RPC_AUD_DEF_CODEC_AAC;
286 cfg.snd_method = RPC_SND_METHOD_MIDI;
287
288 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
289 rc = audmgr_enable(&audio->audmgr, &cfg);
290 if (rc < 0)
291 return rc;
292
293 if (msm_adsp_enable(audio->audpre)) {
294 audmgr_disable(&audio->audmgr);
295 MM_ERR("msm_adsp_enable(audpre) failed\n");
296 return -ENODEV;
297 }
298 }
299 if (msm_adsp_enable(audio->audrec)) {
300 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
301 audmgr_disable(&audio->audmgr);
302 msm_adsp_disable(audio->audpre);
303 }
304 MM_ERR("msm_adsp_enable(audrec) failed\n");
305 return -ENODEV;
306 }
307
308 audio->enabled = 1;
309 audaac_in_dsp_enable(audio, 1);
310
311 return 0;
312}
313
314/* must be called with audio->lock held */
315static int audaac_in_disable(struct audio_aac_in *audio)
316{
317 if (audio->enabled) {
318 audio->enabled = 0;
319
320 audaac_in_dsp_enable(audio, 0);
321
Manish Dewangan95ae3572011-03-15 14:58:12 +0530322 wait_event_interruptible_timeout(audio->wait_enable,
323 audio->running == 0, 1*HZ);
Manish Dewangan89a9f232012-02-09 17:14:40 +0530324 audio->stopped = 1;
325 wake_up(&audio->wait);
Manish Dewangan95ae3572011-03-15 14:58:12 +0530326 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);
Manish Dewangan95ae3572011-03-15 14:58:12 +0530786 break;
787 }
788 case AUDIO_FLUSH: {
789 MM_DBG("AUDIO_FLUSH\n");
790 audio->rflush = 1;
791 audio->wflush = 1;
792 audaac_ioport_reset(audio);
793 if (audio->running) {
794 audaac_flush_command(audio);
795 rc = wait_event_interruptible(audio->write_wait,
796 !audio->wflush);
797 if (rc < 0) {
798 MM_ERR("AUDIO_FLUSH interrupted\n");
799 rc = -EINTR;
800 }
801 } else {
802 audio->rflush = 0;
803 audio->wflush = 0;
804 }
805 break;
806 }
807 case AUDIO_GET_CONFIG: {
808 struct msm_audio_config cfg;
809 memset(&cfg, 0, sizeof(cfg));
810 cfg.buffer_size = OUT_BUFFER_SIZE;
811 cfg.buffer_count = OUT_FRAME_NUM;
812 cfg.sample_rate = convert_samp_index(audio->samp_rate);
813 cfg.channel_count = 1;
814 cfg.type = 0;
815 cfg.unused[0] = 0;
816 cfg.unused[1] = 0;
817 cfg.unused[2] = 0;
818 if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
819 rc = -EFAULT;
820 else
821 rc = 0;
822 break;
823 }
824 case AUDIO_GET_STREAM_CONFIG: {
825 struct msm_audio_stream_config cfg;
826 memset(&cfg, 0, sizeof(cfg));
827 cfg.buffer_size = audio->buffer_size;
828 cfg.buffer_count = FRAME_NUM;
829 if (copy_to_user((void *)arg, &cfg, sizeof(cfg)))
830 rc = -EFAULT;
831 else
832 rc = 0;
833 break;
834 }
835 case AUDIO_SET_STREAM_CONFIG: {
836 struct msm_audio_stream_config cfg;
837 if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
838 rc = -EFAULT;
839 break;
840 }
841 /* Allow only single frame */
842 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
843 if (cfg.buffer_size != (FRAME_SIZE - 8))
844 rc = -EINVAL;
845 break;
846 } else {
847 if (cfg.buffer_size != (AAC_FRAME_SIZE + 14))
848 rc = -EINVAL;
849 break;
850 }
851 audio->buffer_size = cfg.buffer_size;
852 break;
853 }
854 case AUDIO_GET_AAC_ENC_CONFIG: {
855 struct msm_audio_aac_enc_config cfg;
856 if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO)
857 cfg.channels = 1;
858 else
859 cfg.channels = 2;
860 cfg.sample_rate = convert_samp_index(audio->samp_rate);
861 cfg.bit_rate = audio->bit_rate;
862 cfg.stream_format = AUDIO_AAC_FORMAT_RAW;
863 if (copy_to_user((void *)arg, &cfg, sizeof(cfg)))
864 rc = -EFAULT;
865 break;
866 }
867 case AUDIO_SET_AAC_ENC_CONFIG: {
868 struct msm_audio_aac_enc_config cfg;
869 unsigned int record_quality;
870 if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
871 rc = -EFAULT;
872 break;
873 }
874 if (cfg.stream_format != AUDIO_AAC_FORMAT_RAW) {
875 MM_ERR("unsupported AAC format\n");
876 rc = -EINVAL;
877 break;
878 }
879 record_quality = bitrate_to_record_quality(cfg.sample_rate,
880 cfg.channels, cfg.bit_rate);
881 /* Range of Record Quality Supported by DSP, Q12 format */
882 if ((record_quality < 0x800) || (record_quality > 0x4000)) {
883 MM_ERR("Unsupported bit rate\n");
884 rc = -EINVAL;
885 break;
886 }
887 MM_DBG("channels = %d\n", cfg.channels);
888 if (cfg.channels == 1) {
889 cfg.channels = AUDREC_CMD_STEREO_MODE_MONO;
890 } else if (cfg.channels == 2) {
891 cfg.channels = AUDREC_CMD_STEREO_MODE_STEREO;
892 } else {
893 rc = -EINVAL;
894 break;
895 }
896
897 audio->samp_rate = convert_samp_rate(cfg.sample_rate);
898 audio->samp_rate_index =
899 convert_dsp_samp_index(cfg.sample_rate);
900 audio->channel_mode = cfg.channels;
901 audio->bit_rate = cfg.bit_rate;
902 audio->record_quality = record_quality;
903 MM_DBG(" Record Quality = 0x%8x\n", audio->record_quality);
904 break;
905 }
906
907 default:
908 rc = -EINVAL;
909 }
910 mutex_unlock(&audio->lock);
911 return rc;
912}
913
914static ssize_t audaac_in_read(struct file *file,
915 char __user *buf,
916 size_t count, loff_t *pos)
917{
918 struct audio_aac_in *audio = file->private_data;
919 unsigned long flags;
920 const char __user *start = buf;
921 void *data;
922 uint32_t index;
923 uint32_t size;
924 int rc = 0;
925 struct aac_encoded_meta_out meta_field;
926 struct audio_frame_nt *nt_frame;
927 MM_DBG("count = %d\n", count);
928 mutex_lock(&audio->read_lock);
929 while (count > 0) {
930 rc = wait_event_interruptible(
931 audio->wait, (audio->in_count > 0) || audio->stopped ||
932 audio->rflush);
933 if (rc < 0)
934 break;
935
936 if (audio->rflush) {
937 rc = -EBUSY;
938 break;
939 }
940 if (audio->stopped && !audio->in_count) {
941 MM_DBG("Driver in stop state, No more buffer to read");
942 rc = 0;/* End of File */
943 break;
944 }
945
946 index = audio->in_tail;
947 data = (uint8_t *) audio->in[index].data;
948 size = audio->in[index].size;
949
950 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
951 nt_frame = (struct audio_frame_nt *)(data -
952 sizeof(struct audio_frame_nt));
953 memcpy((char *)&meta_field.time_stamp_dword_lsw,
954 (char *)&nt_frame->time_stamp_dword_lsw,
955 (sizeof(struct aac_encoded_meta_out) - \
956 sizeof(uint16_t)));
957 meta_field.metadata_len =
958 sizeof(struct aac_encoded_meta_out);
959 if (copy_to_user((char *)start, (char *)&meta_field,
960 sizeof(struct aac_encoded_meta_out))) {
961 rc = -EFAULT;
962 break;
963 }
964 if (nt_frame->nflag_lsw & 0x0001) {
965 MM_DBG("recieved EOS in read call\n");
966 audio->eos_ack = 1;
967 }
968 buf += sizeof(struct aac_encoded_meta_out);
969 count -= sizeof(struct aac_encoded_meta_out);
970 }
971 if (count >= size) {
972 /* order the reads on the buffer */
973 dma_coherent_post_ops();
974 if (copy_to_user(buf, data, size)) {
975 rc = -EFAULT;
976 break;
977 }
978 spin_lock_irqsave(&audio->dsp_lock, flags);
979 if (index != audio->in_tail) {
980 /* overrun -- data is
981 * invalid and we need to retry */
982 spin_unlock_irqrestore(&audio->dsp_lock, flags);
983 continue;
984 }
985 audio->in[index].size = 0;
986 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
987 audio->in_count--;
988 spin_unlock_irqrestore(&audio->dsp_lock, flags);
989 count -= size;
990 buf += size;
991 if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)) {
992 if (!audio->eos_ack) {
993 MM_DBG("sending read ptr command \
994 %d %d\n",
995 audio->dsp_cnt,
996 audio->in_tail);
997 audaac_in_dsp_read_buffer(audio,
998 audio->dsp_cnt++);
999 }
1000 }
1001 } else {
1002 MM_ERR("short read\n");
1003 break;
1004 }
1005 break;
1006 }
1007 mutex_unlock(&audio->read_lock);
1008
1009 if (buf > start)
1010 return buf - start;
1011
1012 return rc;
1013}
1014
1015static void audrec_pcm_send_data(struct audio_aac_in *audio, unsigned needed)
1016{
1017 struct buffer *frame;
1018 unsigned long flags;
1019 MM_DBG("\n");
1020 spin_lock_irqsave(&audio->dsp_lock, flags);
1021 if (!audio->running)
1022 goto done;
1023
1024 if (needed && !audio->wflush) {
1025 /* We were called from the callback because the DSP
1026 * requested more data. Note that the DSP does want
1027 * more data, and if a buffer was in-flight, mark it
1028 * as available (since the DSP must now be done with
1029 * it).
1030 */
1031 audio->out_needed = 1;
1032 frame = audio->out + audio->out_tail;
1033 if (frame->used == 0xffffffff) {
1034 MM_DBG("frame %d free\n", audio->out_tail);
1035 frame->used = 0;
1036 audio->out_tail ^= 1;
1037 wake_up(&audio->write_wait);
1038 }
1039 }
1040
1041 if (audio->out_needed) {
1042 /* If the DSP currently wants data and we have a
1043 * buffer available, we will send it and reset
1044 * the needed flag. We'll mark the buffer as in-flight
1045 * so that it won't be recycled until the next buffer
1046 * is requested
1047 */
1048
1049 frame = audio->out + audio->out_tail;
1050 if (frame->used) {
1051 BUG_ON(frame->used == 0xffffffff);
1052 audrec_pcm_buffer_ptr_refresh(audio,
1053 audio->out_tail,
1054 frame->used);
1055 frame->used = 0xffffffff;
1056 audio->out_needed = 0;
1057 }
1058 }
1059 done:
1060 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1061}
1062
1063
1064static int audaac_in_fsync(struct file *file, int datasync)
1065
1066{
1067 struct audio_aac_in *audio = file->private_data;
1068 int rc = 0;
1069
1070 MM_DBG("\n"); /* Macro prints the file name and function */
1071 if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) {
1072 rc = -EINVAL;
1073 goto done_nolock;
1074 }
1075
1076 mutex_lock(&audio->write_lock);
1077
1078 rc = wait_event_interruptible(audio->write_wait,
1079 audio->wflush);
1080 MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush);
1081
1082 if (rc < 0)
1083 goto done;
1084 else if (audio->wflush) {
1085 rc = -EBUSY;
1086 goto done;
1087 }
1088done:
1089 mutex_unlock(&audio->write_lock);
1090done_nolock:
1091 return rc;
1092
1093}
1094
1095int audrec_aac_process_eos(struct audio_aac_in *audio,
1096 const char __user *buf_start, unsigned short mfield_size)
1097{
1098 struct buffer *frame;
1099 int rc = 0;
1100
1101 frame = audio->out + audio->out_head;
1102
1103 rc = wait_event_interruptible(audio->write_wait,
1104 (audio->out_needed &&
1105 audio->out[0].used == 0 &&
1106 audio->out[1].used == 0)
1107 || (audio->stopped)
1108 || (audio->wflush));
1109
1110 if (rc < 0)
1111 goto done;
1112 if (audio->stopped || audio->wflush) {
1113 rc = -EBUSY;
1114 goto done;
1115 }
1116 if (copy_from_user(frame->data, buf_start, mfield_size)) {
1117 rc = -EFAULT;
1118 goto done;
1119 }
1120
1121 frame->mfield_sz = mfield_size;
1122 audio->out_head ^= 1;
1123 frame->used = mfield_size;
1124 MM_DBG("copying meta_out frame->used = %d\n", frame->used);
1125 audrec_pcm_send_data(audio, 0);
1126done:
1127 return rc;
1128}
1129static ssize_t audaac_in_write(struct file *file,
1130 const char __user *buf,
1131 size_t count, loff_t *pos)
1132{
1133 struct audio_aac_in *audio = file->private_data;
1134 const char __user *start = buf;
1135 struct buffer *frame;
1136 char *cpy_ptr;
1137 int rc = 0, eos_condition = AUDPREPROC_AAC_EOS_NONE;
1138 unsigned short mfield_size = 0;
1139 int write_count = 0;
1140 MM_DBG("cnt=%d\n", count);
1141
1142 if (count & 1)
1143 return -EINVAL;
1144
1145 if (audio->mode != MSM_AUD_ENC_MODE_NONTUNNEL)
1146 return -EINVAL;
1147
1148 mutex_lock(&audio->write_lock);
1149 frame = audio->out + audio->out_head;
1150 /* if supplied count is more than driver buffer size
1151 * then only copy driver buffer size
1152 */
1153 if (count > frame->size)
1154 count = frame->size;
1155
1156 write_count = count;
1157 cpy_ptr = frame->data;
1158 rc = wait_event_interruptible(audio->write_wait,
1159 (frame->used == 0)
1160 || (audio->stopped)
1161 || (audio->wflush));
1162 if (rc < 0)
1163 goto error;
1164
1165 if (audio->stopped || audio->wflush) {
1166 rc = -EBUSY;
1167 goto error;
1168 }
1169 if (audio->mfield) {
1170 if (buf == start) {
1171 /* Processing beginning of user buffer */
1172 if (__get_user(mfield_size,
1173 (unsigned short __user *) buf)) {
1174 rc = -EFAULT;
1175 goto error;
1176 } else if (mfield_size > count) {
1177 rc = -EINVAL;
1178 goto error;
1179 }
1180 MM_DBG("mf offset_val %x\n", mfield_size);
1181 if (copy_from_user(cpy_ptr, buf, mfield_size)) {
1182 rc = -EFAULT;
1183 goto error;
1184 }
1185 /* Check if EOS flag is set and buffer has
1186 * contains just meta field
1187 */
1188 if (cpy_ptr[AUDPREPROC_AAC_EOS_FLG_OFFSET] &
1189 AUDPREPROC_AAC_EOS_FLG_MASK) {
1190 eos_condition = AUDPREPROC_AAC_EOS_SET;
1191 MM_DBG("EOS SET\n");
1192 if (mfield_size == count) {
1193 buf += mfield_size;
1194 eos_condition = 0;
1195 goto exit;
1196 } else
1197 cpy_ptr[AUDPREPROC_AAC_EOS_FLG_OFFSET] &=
1198 ~AUDPREPROC_AAC_EOS_FLG_MASK;
1199 }
1200 cpy_ptr += mfield_size;
1201 count -= mfield_size;
1202 buf += mfield_size;
1203 } else {
1204 mfield_size = 0;
1205 MM_DBG("continuous buffer\n");
1206 }
1207 frame->mfield_sz = mfield_size;
1208 }
1209 MM_DBG("copying the stream count = %d\n", count);
1210 if (copy_from_user(cpy_ptr, buf, count)) {
1211 rc = -EFAULT;
1212 goto error;
1213 }
1214exit:
1215 frame->used = count;
1216 audio->out_head ^= 1;
1217 if (!audio->flush_ack)
1218 audrec_pcm_send_data(audio, 0);
1219 else {
1220 audrec_pcm_send_data(audio, 1);
1221 audio->flush_ack = 0;
1222 }
1223 if (eos_condition == AUDPREPROC_AAC_EOS_SET)
1224 rc = audrec_aac_process_eos(audio, start, mfield_size);
1225 mutex_unlock(&audio->write_lock);
1226 return write_count;
1227error:
1228 mutex_unlock(&audio->write_lock);
1229 return rc;
1230}
1231
1232static int audaac_in_release(struct inode *inode, struct file *file)
1233{
1234 struct audio_aac_in *audio = file->private_data;
1235
1236 mutex_lock(&audio->lock);
1237 audaac_in_disable(audio);
1238 audaac_in_flush(audio);
1239 msm_adsp_put(audio->audrec);
1240
1241 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
1242 msm_adsp_put(audio->audpre);
1243
1244 audpreproc_aenc_free(audio->enc_id);
1245 audio->audrec = NULL;
1246 audio->audpre = NULL;
1247 audio->opened = 0;
1248
1249 if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) && \
1250 (audio->out_data)) {
Laura Abbott35111d32012-04-27 18:41:48 -07001251 iounmap(audio->map_v_write);
Manish Dewangan95ae3572011-03-15 14:58:12 +05301252 free_contiguous_memory_by_paddr(audio->out_phys);
1253 audio->out_data = NULL;
1254 }
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301255
1256 if (audio->data) {
Laura Abbott35111d32012-04-27 18:41:48 -07001257 iounmap(audio->map_v_read);
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301258 free_contiguous_memory_by_paddr(audio->phys);
1259 audio->data = NULL;
1260 }
Manish Dewangan95ae3572011-03-15 14:58:12 +05301261 mutex_unlock(&audio->lock);
1262 return 0;
1263}
1264
1265struct audio_aac_in the_audio_aac_in;
1266
1267static int audaac_in_open(struct inode *inode, struct file *file)
1268{
1269 struct audio_aac_in *audio = &the_audio_aac_in;
1270 int rc;
1271 int encid;
1272 int dma_size = 0;
1273
1274 mutex_lock(&audio->lock);
1275 if (audio->opened) {
1276 rc = -EBUSY;
1277 goto done;
1278 }
1279 if ((file->f_mode & FMODE_WRITE) &&
1280 (file->f_mode & FMODE_READ)) {
1281 audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL;
1282 dma_size = NT_DMASZ;
1283 MM_DBG("Opened for non tunnel mode encoding\n");
1284 } else if (!(file->f_mode & FMODE_WRITE) &&
1285 (file->f_mode & FMODE_READ)) {
1286 audio->mode = MSM_AUD_ENC_MODE_TUNNEL;
1287 dma_size = DMASZ;
1288 MM_DBG("Opened for tunnel mode encoding\n");
1289 } else {
1290 MM_ERR("Invalid mode\n");
1291 rc = -EACCES;
1292 goto done;
1293 }
1294
1295 /* Settings will be re-config at AUDIO_SET_CONFIG,
1296 * but at least we need to have initial config
1297 */
1298 audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025;
1299 audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025;
1300
1301 /* For AAC, bit rate hard coded, default settings is
1302 * sample rate (11025) x channel count (1) x recording quality (1.75)
1303 * = 19293 bps */
1304 audio->bit_rate = 19293;
1305 audio->record_quality = 0x1c00;
1306
1307 audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO;
1308 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)
1309 audio->buffer_size = (AAC_FRAME_SIZE + 14);
1310 else
1311 audio->buffer_size = (FRAME_SIZE - 8);
1312 audio->enc_type = AUDREC_CMD_TYPE_0_INDEX_AAC | audio->mode;
1313
1314 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
1315 rc = audmgr_open(&audio->audmgr);
1316 if (rc)
1317 goto done;
1318 }
1319
1320 encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name,
1321 &audio->queue_ids);
1322 if (encid < 0) {
1323 MM_ERR("No free encoder available\n");
1324 rc = -ENODEV;
1325 goto done;
1326 }
1327 audio->enc_id = encid;
1328
1329 rc = msm_adsp_get(audio->module_name, &audio->audrec,
1330 &audrec_aac_adsp_ops, audio);
1331 if (rc) {
1332 audpreproc_aenc_free(audio->enc_id);
1333 goto done;
1334 }
1335
1336 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
1337 rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
1338 &audpre_aac_adsp_ops, audio);
1339 if (rc) {
1340 msm_adsp_put(audio->audrec);
1341 audpreproc_aenc_free(audio->enc_id);
1342 goto done;
1343 }
1344 }
1345
1346 audio->dsp_cnt = 0;
1347 audio->stopped = 0;
1348 audio->wflush = 0;
1349 audio->rflush = 0;
1350 audio->flush_ack = 0;
1351
1352 audaac_in_flush(audio);
1353 audaac_out_flush(audio);
1354
1355 audio->phys = allocate_contiguous_ebi_nomap(dma_size, SZ_4K);
1356 if (audio->phys) {
Laura Abbott35111d32012-04-27 18:41:48 -07001357 audio->map_v_read = ioremap(
1358 audio->phys, dma_size);
Manish Dewangan95ae3572011-03-15 14:58:12 +05301359 if (IS_ERR(audio->map_v_read)) {
1360 MM_ERR("could not map DMA buffers\n");
1361 rc = -ENOMEM;
1362 free_contiguous_memory_by_paddr(audio->phys);
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301363 goto evt_error;
Manish Dewangan95ae3572011-03-15 14:58:12 +05301364 }
Laura Abbott35111d32012-04-27 18:41:48 -07001365 audio->data = audio->map_v_read;
Manish Dewangan95ae3572011-03-15 14:58:12 +05301366 } else {
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301367 MM_ERR("could not allocate read buffers\n");
Manish Dewangan95ae3572011-03-15 14:58:12 +05301368 rc = -ENOMEM;
Santosh Mardi7faa0fa2011-09-22 15:32:23 +05301369 goto evt_error;
Manish Dewangan95ae3572011-03-15 14:58:12 +05301370 }
1371 MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x\n",\
1372 (int) audio->data, (int) audio->phys);
1373
1374 audio->out_data = NULL;
1375 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
1376 audio->out_phys = allocate_contiguous_ebi_nomap(BUFFER_SIZE,
1377 SZ_4K);
1378 if (!audio->out_phys) {
1379 MM_ERR("could not allocate write buffers\n");
1380 rc = -ENOMEM;
Laura Abbott35111d32012-04-27 18:41:48 -07001381 iounmap(audio->map_v_read);
Manish Dewangan95ae3572011-03-15 14:58:12 +05301382 free_contiguous_memory_by_paddr(audio->phys);
1383 goto evt_error;
1384 } else {
Laura Abbott35111d32012-04-27 18:41:48 -07001385 audio->map_v_write = ioremap(
1386 audio->out_phys, BUFFER_SIZE);
Manish Dewangan95ae3572011-03-15 14:58:12 +05301387 if (IS_ERR(audio->map_v_write)) {
1388 MM_ERR("could not map write phys address\n");
1389 rc = -ENOMEM;
Laura Abbott35111d32012-04-27 18:41:48 -07001390 iounmap(audio->map_v_read);
Manish Dewangan95ae3572011-03-15 14:58:12 +05301391 free_contiguous_memory_by_paddr(audio->phys);
1392 free_contiguous_memory_by_paddr(\
1393 audio->out_phys);
1394 goto evt_error;
1395 }
Laura Abbott35111d32012-04-27 18:41:48 -07001396 audio->out_data = audio->map_v_write;
Manish Dewangan95ae3572011-03-15 14:58:12 +05301397 MM_DBG("wr buf: phy addr 0x%08x kernel addr 0x%08x\n",
1398 audio->out_phys, (int)audio->out_data);
1399 }
1400
1401 /* Initialize buffer */
1402 audio->out[0].data = audio->out_data + 0;
1403 audio->out[0].addr = audio->out_phys + 0;
1404 audio->out[0].size = OUT_BUFFER_SIZE;
1405
1406 audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE;
1407 audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE;
1408 audio->out[1].size = OUT_BUFFER_SIZE;
1409
1410 MM_DBG("audio->out[0].data = %d audio->out[1].data = %d",
1411 (unsigned int)audio->out[0].data,
1412 (unsigned int)audio->out[1].data);
1413 audio->mfield = NT_FRAME_HEADER_SIZE;
1414 audio->out_frame_cnt++;
1415 }
1416 file->private_data = audio;
1417 audio->opened = 1;
1418
1419done:
1420 mutex_unlock(&audio->lock);
1421 return rc;
1422evt_error:
1423 msm_adsp_put(audio->audrec);
1424 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
1425 msm_adsp_put(audio->audpre);
1426
1427 audpreproc_aenc_free(audio->enc_id);
1428 mutex_unlock(&audio->lock);
1429 return rc;
1430}
1431
1432static const struct file_operations audio_aac_in_fops = {
1433 .owner = THIS_MODULE,
1434 .open = audaac_in_open,
1435 .release = audaac_in_release,
1436 .read = audaac_in_read,
1437 .write = audaac_in_write,
1438 .fsync = audaac_in_fsync,
1439 .unlocked_ioctl = audaac_in_ioctl,
1440};
1441
1442static struct miscdevice audaac_in_misc = {
1443 .minor = MISC_DYNAMIC_MINOR,
1444 .name = "msm_aac_in",
1445 .fops = &audio_aac_in_fops,
1446};
1447
1448static int __init audaac_in_init(void)
1449{
1450 mutex_init(&the_audio_aac_in.lock);
1451 mutex_init(&the_audio_aac_in.read_lock);
1452 spin_lock_init(&the_audio_aac_in.dsp_lock);
1453 init_waitqueue_head(&the_audio_aac_in.wait);
1454 init_waitqueue_head(&the_audio_aac_in.wait_enable);
1455 mutex_init(&the_audio_aac_in.write_lock);
1456 init_waitqueue_head(&the_audio_aac_in.write_wait);
1457 return misc_register(&audaac_in_misc);
1458}
1459device_initcall(audaac_in_init);