blob: cf1f58d40028470d9b0d2b0fd7bfee45308feb47 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/*
2 * aac audio input device
3 *
4 * Copyright (C) 2008 Google, Inc.
5 * Copyright (C) 2008 HTC Corporation
Duy Truong790f06d2013-02-13 16:38:12 -08006 * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
Santosh Mardifdc227a2011-07-11 17:20:34 +053019#include <asm/atomic.h>
20#include <asm/ioctls.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070021#include <linux/module.h>
22#include <linux/fs.h>
23#include <linux/miscdevice.h>
24#include <linux/uaccess.h>
25#include <linux/sched.h>
26#include <linux/wait.h>
27#include <linux/dma-mapping.h>
28#include <linux/msm_audio_aac.h>
Santosh Mardifdc227a2011-07-11 17:20:34 +053029#include <linux/memory_alloc.h>
30#include <mach/msm_memtypes.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070031
32#include <mach/msm_adsp.h>
Santosh Mardifdc227a2011-07-11 17:20:34 +053033#include <mach/iommu.h>
Santosh Mardifdc227a2011-07-11 17:20:34 +053034#include <mach/iommu_domains.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070035#include <mach/qdsp5v2/qdsp5audreccmdi.h>
36#include <mach/qdsp5v2/qdsp5audrecmsg.h>
37#include <mach/qdsp5v2/audpreproc.h>
38#include <mach/qdsp5v2/audio_dev_ctl.h>
39#include <mach/debug_mm.h>
Kalyani polepeddy7413d2b2011-10-14 15:42:15 +053040#include <mach/socinfo.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070041
42/* FRAME_NUM must be a power of two */
43#define FRAME_NUM (8)
44#define FRAME_SIZE (772 * 2) /* 1536 bytes data */
45#define NT_FRAME_SIZE (780 * 2) /* 1536 bytes data + 24 meta field*/
46#define AAC_FRAME_SIZE 1536
47#define DMASZ (FRAME_SIZE * FRAME_NUM)
48#define OUT_FRAME_NUM (2)
49#define META_OUT_SIZE (24)
50#define META_IN_SIZE (14)
51#define OUT_BUFFER_SIZE (32 * 1024 + META_OUT_SIZE)
52#define BUFFER_SIZE (OUT_BUFFER_SIZE * OUT_FRAME_NUM)
53
54#define AUDPREPROC_AAC_EOS_FLG_OFFSET 0x0A /* Offset from beginning of buffer */
55#define AUDPREPROC_AAC_EOS_FLG_MASK 0x01
56#define AUDPREPROC_AAC_EOS_NONE 0x0 /* No EOS detected */
57#define AUDPREPROC_AAC_EOS_SET 0x1 /* EOS set in meta field */
58
59#define PCM_CONFIG_UPDATE_FLAG_ENABLE -1
60#define PCM_CONFIG_UPDATE_FLAG_DISABLE 0
61
62#define ENABLE_FLAG_VALUE -1
63#define DISABLE_FLAG_VALUE 0
64
65struct buffer {
66 void *data;
67 uint32_t size;
68 uint32_t read;
69 uint32_t addr;
70 uint32_t used;
71 uint32_t mfield_sz;
72};
73
74struct audio_in {
75 struct buffer in[FRAME_NUM];
76
77 spinlock_t dsp_lock;
78
79 atomic_t in_bytes;
80 atomic_t in_samples;
81
82 struct mutex lock;
83 struct mutex read_lock;
84 wait_queue_head_t wait;
85 wait_queue_head_t wait_enable;
86 /*write section*/
87 struct buffer out[OUT_FRAME_NUM];
88
89 uint8_t out_head;
90 uint8_t out_tail;
91 uint8_t out_needed; /* number of buffers the dsp is waiting for */
92 uint32_t out_count;
93
94 struct mutex write_lock;
95 wait_queue_head_t write_wait;
96 int32_t out_phys; /* physical address of write buffer */
97 char *out_data;
Laura Abbott61399692012-04-30 14:25:46 -070098 void *map_v_read;
99 void *map_v_write;
Santosh Mardifdc227a2011-07-11 17:20:34 +0530100
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700101 int mfield; /* meta field embedded in data */
102 int wflush; /*write flush */
103 int rflush; /*read flush*/
104 int out_frame_cnt;
105
106 struct msm_adsp_module *audrec;
107
108 /* configuration to use on next enable */
109 uint32_t buffer_size; /* Frame size (36 bytes) */
110 uint32_t samp_rate;
111 uint32_t channel_mode;
112 uint32_t bit_rate; /* bit rate for AAC */
113 uint32_t record_quality; /* record quality (bits/sample/channel) */
114 uint32_t enc_type;
115
116 uint32_t dsp_cnt;
117 uint32_t in_head; /* next buffer dsp will write */
118 uint32_t in_tail; /* next buffer read() will read */
119 uint32_t in_count; /* number of buffers available to read() */
120 uint32_t mode;
121 uint32_t eos_ack;
122 uint32_t flush_ack;
123
124 const char *module_name;
125 unsigned queue_ids;
126 uint16_t enc_id;
127
128 struct audrec_session_info session_info; /*audrec session info*/
129 uint16_t source; /* Encoding source bit mask */
130 uint32_t device_events; /* device events interested in */
131 uint32_t dev_cnt;
132 spinlock_t dev_lock;
133
134 /* data allocated for various buffers */
135 char *data;
136 dma_addr_t phys;
137
138 int opened;
139 int enabled;
140 int running;
141 int stopped; /* set when stopped, cleared on flush */
142 int abort; /* set when error, like sample rate mismatch */
Kalyani polepeddy7413d2b2011-10-14 15:42:15 +0530143 char *build_id;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700144};
145
146struct audio_frame {
147 uint16_t frame_count_lsw;
148 uint16_t frame_count_msw;
149 uint16_t frame_length;
150 uint16_t erased_pcm;
151 unsigned char raw_bitstream[]; /* samples */
152} __attribute__((packed));
153
154struct audio_frame_nt {
155 uint16_t metadata_len;
156 uint16_t frame_count_lsw;
157 uint16_t frame_count_msw;
158 uint16_t frame_length;
159 uint16_t erased_pcm;
160 uint16_t reserved;
161 uint16_t time_stamp_dword_lsw;
162 uint16_t time_stamp_dword_msw;
163 uint16_t time_stamp_lsw;
164 uint16_t time_stamp_msw;
165 uint16_t nflag_lsw;
166 uint16_t nflag_msw;
167 unsigned char raw_bitstream[]; /* samples */
168} __attribute__((packed));
169
170struct aac_encoded_meta_in {
171 uint16_t metadata_len;
172 uint16_t time_stamp_dword_lsw;
173 uint16_t time_stamp_dword_msw;
174 uint16_t time_stamp_lsw;
175 uint16_t time_stamp_msw;
176 uint16_t nflag_lsw;
177 uint16_t nflag_msw;
178};
179
180/* Audrec Queue command sent macro's */
181#define audrec_send_bitstreamqueue(audio, cmd, len) \
182 msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\
183 cmd, len)
184
185#define audrec_send_audrecqueue(audio, cmd, len) \
186 msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\
187 cmd, len)
188
189/* DSP command send functions */
190static int audaac_in_enc_config(struct audio_in *audio, int enable);
191static int audaac_in_param_config(struct audio_in *audio);
192static int audaac_in_mem_config(struct audio_in *audio);
193static int audaac_in_record_config(struct audio_in *audio, int enable);
194static int audaac_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt);
195
196static void audaac_in_get_dsp_frames(struct audio_in *audio);
197static int audpcm_config(struct audio_in *audio);
198static void audaac_out_flush(struct audio_in *audio);
199static int audpreproc_cmd_cfg_routing_mode(struct audio_in *audio);
200static void audpreproc_pcm_send_data(struct audio_in *audio, unsigned needed);
201static void audaac_nt_in_get_dsp_frames(struct audio_in *audio);
202
203static void audaac_in_flush(struct audio_in *audio);
204
205static void aac_in_listener(u32 evt_id, union auddev_evt_data *evt_payload,
206 void *private_data)
207{
208 struct audio_in *audio = (struct audio_in *) private_data;
209 unsigned long flags;
210
211 MM_DBG("evt_id = 0x%8x\n", evt_id);
212 switch (evt_id) {
213 case AUDDEV_EVT_DEV_RDY: {
214 MM_DBG("AUDDEV_EVT_DEV_RDY\n");
215 spin_lock_irqsave(&audio->dev_lock, flags);
216 audio->dev_cnt++;
217 audio->source |= (0x1 << evt_payload->routing_id);
218 spin_unlock_irqrestore(&audio->dev_lock, flags);
219
220 if ((audio->running == 1) && (audio->enabled == 1) &&
221 (audio->mode == MSM_AUD_ENC_MODE_TUNNEL))
222 audaac_in_record_config(audio, 1);
223
224 break;
225 }
226 case AUDDEV_EVT_DEV_RLS: {
227 MM_DBG("AUDDEV_EVT_DEV_RLS\n");
228 spin_lock_irqsave(&audio->dev_lock, flags);
229 audio->dev_cnt--;
230 audio->source &= ~(0x1 << evt_payload->routing_id);
231 spin_unlock_irqrestore(&audio->dev_lock, flags);
232
233 if ((!audio->running) || (!audio->enabled))
234 break;
235
236 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
237 /* Turn of as per source */
238 if (audio->source)
239 audaac_in_record_config(audio, 1);
240 else
241 /* Turn off all */
242 audaac_in_record_config(audio, 0);
243 }
244 break;
245 }
246 case AUDDEV_EVT_FREQ_CHG: {
247 MM_DBG("Encoder Driver got sample rate change event\n");
248 MM_DBG("sample rate %d\n", evt_payload->freq_info.sample_rate);
249 MM_DBG("dev_type %d\n", evt_payload->freq_info.dev_type);
250 MM_DBG("acdb_dev_id %d\n", evt_payload->freq_info.acdb_dev_id);
251 if ((audio->running == 1) && (audio->enabled == 1)) {
252 /* Stop Recording sample rate does not match
253 with device sample rate */
254 if (evt_payload->freq_info.sample_rate !=
255 audio->samp_rate) {
256 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
257 audaac_in_record_config(audio, 0);
258 audio->abort = 1;
259 wake_up(&audio->wait);
260 }
261 }
262 break;
263 }
264 default:
265 MM_ERR("wrong event %d\n", evt_id);
266 break;
267 }
268}
269
270/* Convert Bit Rate to Record Quality field of DSP */
271static unsigned int bitrate_to_record_quality(unsigned int sample_rate,
272 unsigned int channel, unsigned int bit_rate) {
273 unsigned int temp;
274
275 temp = sample_rate * channel;
276 MM_DBG(" sample rate * channel = %d \n", temp);
277 /* To represent in Q12 fixed format */
278 temp = (bit_rate * 4096) / temp;
279 MM_DBG(" Record Quality = 0x%8x \n", temp);
280 return temp;
281}
282
283/* ------------------- dsp preproc event handler--------------------- */
284static void audpreproc_dsp_event(void *data, unsigned id, void *msg)
285{
286 struct audio_in *audio = data;
287
288 switch (id) {
289 case AUDPREPROC_ERROR_MSG: {
290 struct audpreproc_err_msg *err_msg = msg;
291
292 MM_ERR("ERROR_MSG: stream id %d err idx %d\n",
293 err_msg->stream_id, err_msg->aud_preproc_err_idx);
294 /* Error case */
295 wake_up(&audio->wait_enable);
296 break;
297 }
298 case AUDPREPROC_CMD_CFG_DONE_MSG: {
299 MM_DBG("CMD_CFG_DONE_MSG \n");
300 break;
301 }
302 case AUDPREPROC_CMD_ENC_CFG_DONE_MSG: {
303 struct audpreproc_cmd_enc_cfg_done_msg *enc_cfg_msg = msg;
304
305 MM_DBG("CMD_ENC_CFG_DONE_MSG: stream id %d enc type \
306 0x%8x\n", enc_cfg_msg->stream_id,
307 enc_cfg_msg->rec_enc_type);
308 /* Encoder enable success */
309 if (enc_cfg_msg->rec_enc_type & ENCODE_ENABLE) {
310 if(audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
311 MM_DBG("routing command\n");
312 audpreproc_cmd_cfg_routing_mode(audio);
313 } else {
314 audaac_in_param_config(audio);
315 }
316 } else { /* Encoder disable success */
317 audio->running = 0;
318 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
319 audaac_in_record_config(audio, 0);
320 else
321 wake_up(&audio->wait_enable);
322 }
323 break;
324 }
325 case AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG: {
326 MM_DBG("CMD_ENC_PARAM_CFG_DONE_MSG\n");
327 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)
328 audaac_in_mem_config(audio);
329 else
330 audpcm_config(audio);
331 break;
332 }
333 case AUDPREPROC_CMD_ROUTING_MODE_DONE_MSG: {
334 struct audpreproc_cmd_routing_mode_done\
335 *routing_cfg_done_msg = msg;
336 if (routing_cfg_done_msg->configuration == 0) {
337 MM_INFO("routing configuration failed\n");
338 audio->running = 0;
339 } else
340 audaac_in_param_config(audio);
341 break;
342 }
343 case AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG: {
344 MM_DBG("AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG\n");
345 wake_up(&audio->wait_enable);
346 break;
347 }
348 default:
349 MM_ERR("Unknown Event id %d\n", id);
350 }
351}
352
353/* ------------------- dsp audrec event handler--------------------- */
354static void audrec_dsp_event(void *data, unsigned id, size_t len,
355 void (*getevent)(void *ptr, size_t len))
356{
357 struct audio_in *audio = data;
358
359 switch (id) {
360 case AUDREC_CMD_MEM_CFG_DONE_MSG: {
361 MM_DBG("CMD_MEM_CFG_DONE MSG DONE\n");
362 audio->running = 1;
363 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
364 if (audio->dev_cnt > 0)
365 audaac_in_record_config(audio, 1);
366 } else {
367 audpreproc_pcm_send_data(audio, 1);
368 wake_up(&audio->wait_enable);
369 }
370 break;
371 }
372 case AUDREC_FATAL_ERR_MSG: {
373 struct audrec_fatal_err_msg fatal_err_msg;
374
375 getevent(&fatal_err_msg, AUDREC_FATAL_ERR_MSG_LEN);
376 MM_ERR("FATAL_ERR_MSG: err id %d\n",
377 fatal_err_msg.audrec_err_id);
378 /* Error stop the encoder */
379 audio->stopped = 1;
380 wake_up(&audio->wait);
381 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)
382 wake_up(&audio->write_wait);
383 break;
384 }
385 case AUDREC_UP_PACKET_READY_MSG: {
386 struct audrec_up_pkt_ready_msg pkt_ready_msg;
387
388 getevent(&pkt_ready_msg, AUDREC_UP_PACKET_READY_MSG_LEN);
389 MM_DBG("UP_PACKET_READY_MSG: write cnt lsw %d \
390 write cnt msw %d read cnt lsw %d read cnt msw %d \n",\
391 pkt_ready_msg.audrec_packet_write_cnt_lsw, \
392 pkt_ready_msg.audrec_packet_write_cnt_msw, \
393 pkt_ready_msg.audrec_up_prev_read_cnt_lsw, \
394 pkt_ready_msg.audrec_up_prev_read_cnt_msw);
395
396 audaac_in_get_dsp_frames(audio);
397 break;
398 }
399 case AUDREC_CMD_PCM_BUFFER_PTR_UPDATE_ARM_TO_ENC_MSG: {
400 MM_DBG("ptr_update recieved from DSP\n");
401 audpreproc_pcm_send_data(audio, 1);
402 break;
403 }
404 case AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG: {
405 MM_ERR("AUDREC_CMD_PCM_CFG_ARM_TO_ENC_DONE_MSG");
406 audaac_in_mem_config(audio);
407 break;
408 }
409 case AUDREC_UP_NT_PACKET_READY_MSG: {
410 struct audrec_up_nt_packet_ready_msg pkt_ready_msg;
411
412 getevent(&pkt_ready_msg, AUDREC_UP_NT_PACKET_READY_MSG_LEN);
413 MM_DBG("UP_NT_PACKET_READY_MSG: write cnt lsw %d \
414 write cnt msw %d read cnt lsw %d read cnt msw %d \n",\
415 pkt_ready_msg.audrec_packetwrite_cnt_lsw, \
416 pkt_ready_msg.audrec_packetwrite_cnt_msw, \
417 pkt_ready_msg.audrec_upprev_readcount_lsw, \
418 pkt_ready_msg.audrec_upprev_readcount_msw);
419
420 audaac_nt_in_get_dsp_frames(audio);
421 break;
422 }
423 case AUDREC_CMD_EOS_ACK_MSG: {
424 MM_DBG("eos ack recieved\n");
425 break;
426 }
427 case AUDREC_CMD_FLUSH_DONE_MSG: {
428 audio->wflush = 0;
429 audio->rflush = 0;
430 audio->flush_ack = 1;
431 wake_up(&audio->write_wait);
432 MM_DBG("flush ack recieved\n");
433 break;
434 }
435 case ADSP_MESSAGE_ID: {
436 MM_DBG("Received ADSP event:module audrectask\n");
437 break;
438 }
439 default:
440 MM_ERR("Unknown Event id %d\n", id);
441 }
442}
443
444static void audaac_in_get_dsp_frames(struct audio_in *audio)
445{
446 struct audio_frame *frame;
447 uint32_t index;
448 unsigned long flags;
449
450 MM_DBG("head = %d\n", audio->in_head);
451 index = audio->in_head;
452
453 frame = (void *) (((char *)audio->in[index].data) - \
454 sizeof(*frame));
455
456 spin_lock_irqsave(&audio->dsp_lock, flags);
457 audio->in[index].size = frame->frame_length;
458
459 /* statistics of read */
460 atomic_add(audio->in[index].size, &audio->in_bytes);
461 atomic_add(1, &audio->in_samples);
462
463 audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1);
464
465 /* If overflow, move the tail index foward. */
466 if (audio->in_head == audio->in_tail) {
467 MM_ERR("Error! not able to keep up the read\n");
468 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
469 } else
470 audio->in_count++;
471
472 audaac_dsp_read_buffer(audio, audio->dsp_cnt++);
473 spin_unlock_irqrestore(&audio->dsp_lock, flags);
474
475 wake_up(&audio->wait);
476}
477
478static void audaac_nt_in_get_dsp_frames(struct audio_in *audio)
479{
480 struct audio_frame_nt *nt_frame;
481 uint32_t index;
482 unsigned long flags;
483 MM_DBG("head = %d\n", audio->in_head);
484 index = audio->in_head;
485 nt_frame = (void *) (((char *)audio->in[index].data) - \
486 sizeof(struct audio_frame_nt));
487 spin_lock_irqsave(&audio->dsp_lock, flags);
488 audio->in[index].size = nt_frame->frame_length;
489 /* statistics of read */
490 atomic_add(audio->in[index].size, &audio->in_bytes);
491 atomic_add(1, &audio->in_samples);
492
493 audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1);
494
495 /* If overflow, move the tail index foward. */
496 if (audio->in_head == audio->in_tail)
497 MM_DBG("Error! not able to keep up the read\n");
498 else
499 audio->in_count++;
500
501 spin_unlock_irqrestore(&audio->dsp_lock, flags);
502 wake_up(&audio->wait);
503}
504
505
506struct msm_adsp_ops audrec_aac_adsp_ops = {
507 .event = audrec_dsp_event,
508};
509
510static int audpreproc_pcm_buffer_ptr_refresh(struct audio_in *audio,
511 unsigned idx, unsigned len)
512{
513 struct audrec_cmd_pcm_buffer_ptr_refresh_arm_enc cmd;
514
515 if (len == META_OUT_SIZE)
516 len = len / 2;
517 else
518 len = (len + META_OUT_SIZE) / 2;
519 MM_DBG("len = %d\n", len);
520 memset(&cmd, 0, sizeof(cmd));
521 cmd.cmd_id = AUDREC_CMD_PCM_BUFFER_PTR_REFRESH_ARM_TO_ENC;
522 cmd.num_buffers = 1;
523 if (cmd.num_buffers == 1) {
524 cmd.buf_address_length[0] = (audio->out[idx].addr &
525 0xffff0000) >> 16;
526 cmd.buf_address_length[1] = (audio->out[idx].addr &
527 0x0000ffff);
528 cmd.buf_address_length[2] = (len & 0xffff0000) >> 16;
529 cmd.buf_address_length[3] = (len & 0x0000ffff);
530 }
531 audio->out_frame_cnt++;
532 return audrec_send_audrecqueue(audio, (void *)&cmd,
533 (unsigned int)sizeof(cmd));
534}
535
536
537static int audpcm_config(struct audio_in *audio)
538{
539 struct audrec_cmd_pcm_cfg_arm_to_enc cmd;
540 MM_DBG("\n");
541 memset(&cmd, 0, sizeof(cmd));
542 cmd.cmd_id = AUDREC_CMD_PCM_CFG_ARM_TO_ENC;
543 cmd.config_update_flag = PCM_CONFIG_UPDATE_FLAG_ENABLE;
544 cmd.enable_flag = ENABLE_FLAG_VALUE;
545 cmd.sampling_freq = audio->samp_rate;
546 if (!audio->channel_mode)
547 cmd.channels = 1;
548 else
549 cmd.channels = 2;
550 cmd.frequency_of_intimation = 1;
551 cmd.max_number_of_buffers = OUT_FRAME_NUM;
552 return audrec_send_audrecqueue(audio, (void *)&cmd,
553 (unsigned int)sizeof(cmd));
554}
555
556
557static int audpreproc_cmd_cfg_routing_mode(struct audio_in *audio)
558{
559 struct audpreproc_audrec_cmd_routing_mode cmd;
560
561 MM_DBG("\n");
562 memset(&cmd, 0, sizeof(cmd));
563 cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ROUTING_MODE;
564 cmd.stream_id = audio->enc_id;
565 if (audio->mode == MSM_ADSP_ENC_MODE_NON_TUNNEL)
566 cmd.routing_mode = 1;
567 return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd));
568}
569
570
571
572static int audaac_in_enc_config(struct audio_in *audio, int enable)
573{
574 struct audpreproc_audrec_cmd_enc_cfg cmd;
575 memset(&cmd, 0, sizeof(cmd));
Kalyani polepeddy7413d2b2011-10-14 15:42:15 +0530576 if (audio->build_id[17] == '1') {
577 cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG_2;
578 MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG_2 command");
579 } else {
580 cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG;
581 MM_ERR("sending AUDPREPROC_AUDREC_CMD_ENC_CFG command");
582 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700583 cmd.stream_id = audio->enc_id;
584
585 if (enable)
586 cmd.audrec_enc_type = audio->enc_type | ENCODE_ENABLE;
587 else
588 cmd.audrec_enc_type &= ~(ENCODE_ENABLE);
589
590 return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd));
591}
592
593static int audaac_in_param_config(struct audio_in *audio)
594{
595 struct audpreproc_audrec_cmd_parm_cfg_aac cmd;
596
597 MM_DBG("\n");
598 memset(&cmd, 0, sizeof(cmd));
599 cmd.common.cmd_id = AUDPREPROC_AUDREC_CMD_PARAM_CFG;
600 cmd.common.stream_id = audio->enc_id;
601
602 cmd.aud_rec_samplerate_idx = audio->samp_rate;
603 cmd.aud_rec_stereo_mode = audio->channel_mode;
604 cmd.recording_quality = audio->record_quality;
605
606 return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd));
607}
608
609/* To Do: msm_snddev_route_enc(audio->enc_id); */
610static int audaac_in_record_config(struct audio_in *audio, int enable)
611{
612 struct audpreproc_afe_cmd_audio_record_cfg cmd;
613 MM_DBG("\n");
614 memset(&cmd, 0, sizeof(cmd));
615 cmd.cmd_id = AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG;
616 cmd.stream_id = audio->enc_id;
617 if (enable)
618 cmd.destination_activity = AUDIO_RECORDING_TURN_ON;
619 else
620 cmd.destination_activity = AUDIO_RECORDING_TURN_OFF;
621
622 cmd.source_mix_mask = audio->source;
623 if (audio->enc_id == 2) {
624 if ((cmd.source_mix_mask & INTERNAL_CODEC_TX_SOURCE_MIX_MASK) ||
625 (cmd.source_mix_mask & AUX_CODEC_TX_SOURCE_MIX_MASK) ||
626 (cmd.source_mix_mask & VOICE_UL_SOURCE_MIX_MASK) ||
627 (cmd.source_mix_mask & VOICE_DL_SOURCE_MIX_MASK)) {
628 cmd.pipe_id = SOURCE_PIPE_1;
629 }
630 if (cmd.source_mix_mask &
631 AUDPP_A2DP_PIPE_SOURCE_MIX_MASK)
632 cmd.pipe_id |= SOURCE_PIPE_0;
633 }
634 return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd));
635}
636
637static int audaac_in_mem_config(struct audio_in *audio)
638{
639 struct audrec_cmd_arecmem_cfg cmd;
640 uint16_t *data = (void *) audio->data;
641 int n;
642 memset(&cmd, 0, sizeof(cmd));
643 cmd.cmd_id = AUDREC_CMD_MEM_CFG_CMD;
644 cmd.audrec_up_pkt_intm_count = 1;
645 cmd.audrec_ext_pkt_start_addr_msw = audio->phys >> 16;
646 cmd.audrec_ext_pkt_start_addr_lsw = audio->phys;
647 cmd.audrec_ext_pkt_buf_number = FRAME_NUM;
648 MM_DBG("audio->phys = %x\n", audio->phys);
649 /* prepare buffer pointers:
650 * 1536 bytes aac packet + 4 halfword header
651 */
652 for (n = 0; n < FRAME_NUM; n++) {
653 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
654 audio->in[n].data = data + 4;
655 data += (FRAME_SIZE/2);
656 MM_DBG("0x%8x\n", (int)(audio->in[n].data - 8));
657 } else {
658 audio->in[n].data = data + 12;
659 data += ((AAC_FRAME_SIZE) / 2) + 12;
660 MM_DBG("0x%8x\n", (int)(audio->in[n].data - 24));
661 }
662 }
663 return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd));
664}
665
666static int audaac_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt)
667{
668 struct up_audrec_packet_ext_ptr cmd;
669
670 memset(&cmd, 0, sizeof(cmd));
671 cmd.cmd_id = UP_AUDREC_PACKET_EXT_PTR;
672 cmd.audrec_up_curr_read_count_msw = read_cnt >> 16;
673 cmd.audrec_up_curr_read_count_lsw = read_cnt;
674
675 return audrec_send_bitstreamqueue(audio, &cmd, sizeof(cmd));
676}
677static int audaac_flush_command(struct audio_in *audio)
678{
679 struct audrec_cmd_flush cmd;
680 MM_DBG("\n");
681 memset(&cmd, 0, sizeof(cmd));
682 cmd.cmd_id = AUDREC_CMD_FLUSH;
683 return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd));
684}
685
686/* must be called with audio->lock held */
687static int audaac_in_enable(struct audio_in *audio)
688{
689 if (audio->enabled)
690 return 0;
691
692 if (audpreproc_enable(audio->enc_id, &audpreproc_dsp_event, audio)) {
693 MM_ERR("msm_adsp_enable(audpreproc) failed\n");
694 return -ENODEV;
695 }
696
697 if (msm_adsp_enable(audio->audrec)) {
698 MM_ERR("msm_adsp_enable(audrec) failed\n");
699 audpreproc_disable(audio->enc_id, audio);
700 return -ENODEV;
701 }
702 audio->enabled = 1;
703 audaac_in_enc_config(audio, 1);
704
705 return 0;
706}
707
708/* must be called with audio->lock held */
709static int audaac_in_disable(struct audio_in *audio)
710{
711 if (audio->enabled) {
712 audio->enabled = 0;
713 audaac_in_enc_config(audio, 0);
714 wake_up(&audio->wait);
715 wait_event_interruptible_timeout(audio->wait_enable,
716 audio->running == 0, 1*HZ);
717 msm_adsp_disable(audio->audrec);
718 audpreproc_disable(audio->enc_id, audio);
719 }
720 return 0;
721}
722
723static void audaac_ioport_reset(struct audio_in *audio)
724{
725 /* Make sure read/write thread are free from
726 * sleep and knowing that system is not able
727 * to process io request at the moment
728 */
729 wake_up(&audio->write_wait);
730 mutex_lock(&audio->write_lock);
731 audaac_in_flush(audio);
732 mutex_unlock(&audio->write_lock);
733 wake_up(&audio->wait);
734 mutex_lock(&audio->read_lock);
735 audaac_out_flush(audio);
736 mutex_unlock(&audio->read_lock);
737}
738
739static void audaac_in_flush(struct audio_in *audio)
740{
741 int i;
742
743 audio->dsp_cnt = 0;
744 audio->in_head = 0;
745 audio->in_tail = 0;
746 audio->in_count = 0;
747 audio->eos_ack = 0;
748 for (i = 0; i < FRAME_NUM; i++) {
749 audio->in[i].size = 0;
750 audio->in[i].read = 0;
751 }
752 MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes));
753 MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples));
754 atomic_set(&audio->in_bytes, 0);
755 atomic_set(&audio->in_samples, 0);
756}
757
758static void audaac_out_flush(struct audio_in *audio)
759{
760 int i;
761
762 audio->out_head = 0;
763 audio->out_tail = 0;
764 audio->out_count = 0;
765 for (i = 0; i < OUT_FRAME_NUM; i++) {
766 audio->out[i].size = 0;
767 audio->out[i].read = 0;
768 audio->out[i].used = 0;
769 }
770}
771
772/* ------------------- device --------------------- */
773static long audaac_in_ioctl(struct file *file,
774 unsigned int cmd, unsigned long arg)
775{
776 struct audio_in *audio = file->private_data;
777 int rc = 0;
778
779 if (cmd == AUDIO_GET_STATS) {
780 struct msm_audio_stats stats;
781 stats.byte_count = atomic_read(&audio->in_bytes);
782 stats.sample_count = atomic_read(&audio->in_samples);
783 if (copy_to_user((void *) arg, &stats, sizeof(stats)))
784 return -EFAULT;
785 return rc;
786 }
787
788 mutex_lock(&audio->lock);
789 switch (cmd) {
790 case AUDIO_START: {
791 uint32_t freq;
792 /* Poll at 48KHz always */
793 freq = 48000;
794 MM_DBG("AUDIO_START\n");
795 rc = msm_snddev_request_freq(&freq, audio->enc_id,
796 SNDDEV_CAP_TX, AUDDEV_CLNT_ENC);
797 MM_DBG("sample rate configured %d sample rate requested %d\n",
798 freq, audio->samp_rate);
799 if (rc < 0) {
800 MM_DBG(" Sample rate can not be set, return code %d\n",
801 rc);
802 msm_snddev_withdraw_freq(audio->enc_id,
803 SNDDEV_CAP_TX, AUDDEV_CLNT_ENC);
804 MM_DBG("msm_snddev_withdraw_freq\n");
805 break;
806 }
807 /*update aurec session info in audpreproc layer*/
808 audio->session_info.session_id = audio->enc_id;
809 audio->session_info.sampling_freq = audio->samp_rate;
810 audpreproc_update_audrec_info(&audio->session_info);
811 rc = audaac_in_enable(audio);
812 if (!rc) {
813 rc =
814 wait_event_interruptible_timeout(audio->wait_enable,
815 audio->running != 0, 1*HZ);
816 MM_DBG("state %d rc = %d\n", audio->running, rc);
817
818 if (audio->running == 0)
819 rc = -ENODEV;
820 else
821 rc = 0;
822 }
823 audio->stopped = 0;
824 break;
825 }
826 case AUDIO_STOP: {
827 audio->session_info.sampling_freq = 0;
828 audpreproc_update_audrec_info(&audio->session_info);
829 rc = audaac_in_disable(audio);
830 rc = msm_snddev_withdraw_freq(audio->enc_id,
831 SNDDEV_CAP_TX, AUDDEV_CLNT_ENC);
832 MM_DBG("msm_snddev_withdraw_freq\n");
833 audio->stopped = 1;
834 audio->abort = 0;
835 break;
836 }
837 case AUDIO_FLUSH:
838 MM_DBG("AUDIO_FLUSH\n");
839 audio->rflush = 1;
840 audio->wflush = 1;
841 audaac_ioport_reset(audio);
842 if (audio->running) {
843 audaac_flush_command(audio);
844 rc = wait_event_interruptible(audio->write_wait,
845 !audio->wflush);
846 if (rc < 0) {
847 MM_ERR("AUDIO_FLUSH interrupted\n");
848 rc = -EINTR;
849 }
850 } else {
851 audio->rflush = 0;
852 audio->wflush = 0;
853 }
854 break;
855 case AUDIO_GET_STREAM_CONFIG: {
856 struct msm_audio_stream_config cfg;
857 memset(&cfg, 0, sizeof(cfg));
858 cfg.buffer_size = audio->buffer_size;
859 cfg.buffer_count = FRAME_NUM;
860 if (copy_to_user((void *)arg, &cfg, sizeof(cfg)))
861 rc = -EFAULT;
862 break;
863 }
864 case AUDIO_SET_STREAM_CONFIG: {
865 struct msm_audio_stream_config cfg;
866 if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
867 rc = -EFAULT;
868 break;
869 }
870 /* Allow only single frame */
871 if (audio->mode == MSM_AUD_ENC_MODE_TUNNEL) {
872 if (cfg.buffer_size != (FRAME_SIZE - 8)) {
873 rc = -EINVAL;
874 break;
875 }
876 } else {
877 if (cfg.buffer_size != (NT_FRAME_SIZE - 24)) {
878 rc = -EINVAL;
879 break;
880 }
881 }
882 audio->buffer_size = cfg.buffer_size;
883 break;
884 }
885 case AUDIO_GET_CONFIG: {
886 struct msm_audio_pcm_config cfg;
887 memset(&cfg, 0, sizeof(cfg));
888 cfg.buffer_size = OUT_BUFFER_SIZE;
889 cfg.buffer_count = OUT_FRAME_NUM;
890 if (copy_to_user((void *)arg, &cfg, sizeof(cfg)))
891 rc = -EFAULT;
892 break;
893 }
894 case AUDIO_GET_AAC_ENC_CONFIG: {
895 struct msm_audio_aac_enc_config cfg;
896 if (audio->channel_mode == AUDREC_CMD_MODE_MONO)
897 cfg.channels = 1;
898 else
899 cfg.channels = 2;
900 cfg.sample_rate = audio->samp_rate;
901 cfg.bit_rate = audio->bit_rate;
902 cfg.stream_format = AUDIO_AAC_FORMAT_RAW;
903 if (copy_to_user((void *)arg, &cfg, sizeof(cfg)))
904 rc = -EFAULT;
905 break;
906 }
907 case AUDIO_SET_AAC_ENC_CONFIG: {
908 struct msm_audio_aac_enc_config cfg;
909 unsigned int record_quality;
910 if (copy_from_user(&cfg, (void *)arg, sizeof(cfg))) {
911 rc = -EFAULT;
912 break;
913 }
914 if (cfg.stream_format != AUDIO_AAC_FORMAT_RAW) {
915 MM_ERR("unsupported AAC format\n");
916 rc = -EINVAL;
917 break;
918 }
919 record_quality = bitrate_to_record_quality(cfg.sample_rate,
920 cfg.channels, cfg.bit_rate);
921 /* Range of Record Quality Supported by DSP, Q12 format */
922 if ((record_quality < 0x800) || (record_quality > 0x4000)) {
923 MM_ERR("Unsupported bit rate \n");
924 rc = -EINVAL;
925 break;
926 }
927 MM_DBG("channels = %d\n", cfg.channels);
928 if (cfg.channels == 1) {
929 cfg.channels = AUDREC_CMD_MODE_MONO;
930 } else if (cfg.channels == 2) {
931 cfg.channels = AUDREC_CMD_MODE_STEREO;
932 } else {
933 rc = -EINVAL;
934 break;
935 }
936 MM_DBG("channels = %d\n", cfg.channels);
937 audio->samp_rate = cfg.sample_rate;
938 audio->channel_mode = cfg.channels;
939 audio->bit_rate = cfg.bit_rate;
940 audio->record_quality = record_quality;
941 MM_DBG(" Record Quality = 0x%8x \n", audio->record_quality);
942 break;
943 }
944 case AUDIO_GET_SESSION_ID: {
945 if (copy_to_user((void *) arg, &audio->enc_id,
946 sizeof(unsigned short))) {
947 rc = -EFAULT;
948 }
949 break;
950 }
951 default:
952 rc = -EINVAL;
953 }
954 mutex_unlock(&audio->lock);
955 return rc;
956}
957
958static ssize_t audaac_in_read(struct file *file,
959 char __user *buf,
960 size_t count, loff_t *pos)
961{
962 struct audio_in *audio = file->private_data;
963 unsigned long flags;
964 const char __user *start = buf;
965 void *data;
966 uint32_t index;
967 uint32_t size;
968 int rc = 0;
969 struct aac_encoded_meta_in meta_field;
970 struct audio_frame_nt *nt_frame;
971 MM_DBG(" count = %d\n", count);
972 mutex_lock(&audio->read_lock);
973 while (count > 0) {
974 rc = wait_event_interruptible(
975 audio->wait, (audio->in_count > 0) || audio->stopped ||
976 audio->abort || audio->rflush);
977
978 if (rc < 0)
979 break;
980
981 if (audio->rflush) {
982 rc = -EBUSY;
983 break;
984 }
985
986 if (audio->stopped && !audio->in_count) {
987 MM_DBG("Driver in stop state, No more buffer to read");
988 rc = 0;/* End of File */
989 break;
990 }
991
992 if (audio->abort) {
993 rc = -EPERM; /* Not permitted due to abort */
994 break;
995 }
996
997 index = audio->in_tail;
998 data = (uint8_t *) audio->in[index].data;
999 size = audio->in[index].size;
1000
1001 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) {
1002 nt_frame = (struct audio_frame_nt *)(data -
1003 sizeof(struct audio_frame_nt));
1004 memcpy((char *)&meta_field.time_stamp_dword_lsw,
1005 (char *)&nt_frame->time_stamp_dword_lsw, 12);
1006 meta_field.metadata_len =
1007 sizeof(struct aac_encoded_meta_in);
1008 if (copy_to_user((char *)start, (char *)&meta_field,
1009 sizeof(struct aac_encoded_meta_in))) {
1010 rc = -EFAULT;
1011 break;
1012 }
1013 if (nt_frame->nflag_lsw & 0x0001) {
1014 MM_ERR("recieved EOS in read call\n");
1015 audio->eos_ack = 1;
1016 }
1017 buf += sizeof(struct aac_encoded_meta_in);
1018 count -= sizeof(struct aac_encoded_meta_in);
1019 }
1020 if (count >= size) {
1021 if (copy_to_user(buf, data, size)) {
1022 rc = -EFAULT;
1023 break;
1024 }
1025 spin_lock_irqsave(&audio->dsp_lock, flags);
1026 if (index != audio->in_tail) {
1027 /* overrun -- data is
1028 * invalid and we need to retry */
1029 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1030 continue;
1031 }
1032 audio->in[index].size = 0;
1033 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
1034 audio->in_count--;
1035 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1036 count -= size;
1037 buf += size;
1038 if ((audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL) &&
1039 (!audio->eos_ack)) {
1040 MM_DBG("sending read ptr command %d %d\n",
1041 audio->dsp_cnt,
1042 audio->in_tail);
1043 audaac_dsp_read_buffer(audio,
1044 audio->dsp_cnt++);
1045 break;
1046 }
1047 } else {
1048 MM_ERR("short read\n");
1049 break;
1050 }
1051 break;
1052 }
1053 mutex_unlock(&audio->read_lock);
1054 if (buf > start)
1055 return buf - start;
1056
1057 return rc;
1058}
1059
1060static void audpreproc_pcm_send_data(struct audio_in *audio, unsigned needed)
1061{
1062 struct buffer *frame;
1063 unsigned long flags;
1064 MM_DBG("\n");
1065 spin_lock_irqsave(&audio->dsp_lock, flags);
1066 if (!audio->running)
1067 goto done;
1068
1069 if (needed && !audio->wflush) {
1070 /* We were called from the callback because the DSP
1071 * requested more data. Note that the DSP does want
1072 * more data, and if a buffer was in-flight, mark it
1073 * as available (since the DSP must now be done with
1074 * it).
1075 */
1076 audio->out_needed = 1;
1077 frame = audio->out + audio->out_tail;
1078 if (frame->used == 0xffffffff) {
1079 MM_DBG("frame %d free\n", audio->out_tail);
1080 frame->used = 0;
1081 audio->out_tail ^= 1;
1082 wake_up(&audio->write_wait);
1083 }
1084 }
1085
1086 if (audio->out_needed) {
1087 /* If the DSP currently wants data and we have a
1088 * buffer available, we will send it and reset
1089 * the needed flag. We'll mark the buffer as in-flight
1090 * so that it won't be recycled until the next buffer
1091 * is requested
1092 */
1093
1094 frame = audio->out + audio->out_tail;
1095 if (frame->used) {
1096 BUG_ON(frame->used == 0xffffffff);
1097 MM_DBG("frame %d busy\n", audio->out_tail);
1098 audpreproc_pcm_buffer_ptr_refresh(audio,
1099 audio->out_tail,
1100 frame->used);
1101 frame->used = 0xffffffff;
1102 audio->out_needed = 0;
1103 }
1104 }
1105 done:
1106 spin_unlock_irqrestore(&audio->dsp_lock, flags);
1107}
1108
1109
Steve Mucklef132c6c2012-06-06 18:30:57 -07001110static int audaac_in_fsync(struct file *file, loff_t ppos1, loff_t ppos2, int datasync)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001111
1112{
1113 struct audio_in *audio = file->private_data;
1114 int rc = 0;
1115
1116 MM_DBG("\n"); /* Macro prints the file name and function */
1117 if (!audio->running || (audio->mode == MSM_AUD_ENC_MODE_TUNNEL)) {
1118 rc = -EINVAL;
1119 goto done_nolock;
1120 }
1121
1122 mutex_lock(&audio->write_lock);
1123
1124 rc = wait_event_interruptible(audio->write_wait,
1125 audio->wflush);
1126 MM_DBG("waked on by some event audio->wflush = %d\n", audio->wflush);
1127
1128 if (rc < 0)
1129 goto done;
1130 else if (audio->wflush) {
1131 rc = -EBUSY;
1132 goto done;
1133 }
1134done:
1135 mutex_unlock(&audio->write_lock);
1136done_nolock:
1137 return rc;
1138
1139}
1140
1141 int audpreproc_aac_process_eos(struct audio_in *audio,
1142 const char __user *buf_start, unsigned short mfield_size)
1143{
1144 struct buffer *frame;
1145 int rc = 0;
1146
1147 frame = audio->out + audio->out_head;
1148
1149 rc = wait_event_interruptible(audio->write_wait,
1150 (audio->out_needed &&
1151 audio->out[0].used == 0 &&
1152 audio->out[1].used == 0)
1153 || (audio->stopped)
1154 || (audio->wflush));
1155
1156 if (rc < 0)
1157 goto done;
1158 if (audio->stopped || audio->wflush) {
1159 rc = -EBUSY;
1160 goto done;
1161 }
1162 if (copy_from_user(frame->data, buf_start, mfield_size)) {
1163 rc = -EFAULT;
1164 goto done;
1165 }
1166
1167 frame->mfield_sz = mfield_size;
1168 audio->out_head ^= 1;
1169 frame->used = mfield_size;
1170 MM_DBG("copying meta_out frame->used = %d\n", frame->used);
1171 audpreproc_pcm_send_data(audio, 0);
1172done:
1173 return rc;
1174}
1175
1176static ssize_t audaac_in_write(struct file *file,
1177 const char __user *buf,
1178 size_t count, loff_t *pos)
1179{
1180 struct audio_in *audio = file->private_data;
1181 const char __user *start = buf;
1182 struct buffer *frame;
1183 char *cpy_ptr;
1184 int rc = 0, eos_condition = AUDPREPROC_AAC_EOS_NONE;
1185 unsigned short mfield_size = 0;
1186 int write_count = count;
1187 MM_DBG("cnt=%d\n", count);
1188
1189 if (count & 1)
1190 return -EINVAL;
1191
1192 mutex_lock(&audio->write_lock);
1193 frame = audio->out + audio->out_head;
1194 cpy_ptr = frame->data;
1195 rc = wait_event_interruptible(audio->write_wait,
1196 (frame->used == 0)
1197 || (audio->stopped)
1198 || (audio->wflush));
1199 if (rc < 0)
1200 goto error;
1201
1202 if (audio->stopped || audio->wflush) {
1203 rc = -EBUSY;
1204 goto error;
1205 }
1206 if (audio->mfield) {
1207 if (buf == start) {
1208 /* Processing beginning of user buffer */
1209 if (__get_user(mfield_size,
1210 (unsigned short __user *) buf)) {
1211 rc = -EFAULT;
1212 goto error;
1213 } else if (mfield_size > count) {
1214 rc = -EINVAL;
1215 goto error;
1216 }
1217 MM_DBG("mf offset_val %x\n", mfield_size);
1218 if (copy_from_user(cpy_ptr, buf, mfield_size)) {
1219 rc = -EFAULT;
1220 goto error;
1221 }
1222 /* Check if EOS flag is set and buffer has
1223 * contains just meta field
1224 */
1225 if (cpy_ptr[AUDPREPROC_AAC_EOS_FLG_OFFSET] &
1226 AUDPREPROC_AAC_EOS_FLG_MASK) {
1227 MM_DBG("EOS SET\n");
1228 eos_condition = AUDPREPROC_AAC_EOS_SET;
1229 if (mfield_size == count) {
1230 buf += mfield_size;
1231 if (audio->mode ==
1232 MSM_AUD_ENC_MODE_NONTUNNEL) {
1233 eos_condition = 0;
1234 goto exit;
1235 }
1236 goto error;
1237 } else
1238 cpy_ptr[AUDPREPROC_AAC_EOS_FLG_OFFSET] &=
1239 ~AUDPREPROC_AAC_EOS_FLG_MASK;
1240 }
1241 cpy_ptr += mfield_size;
1242 count -= mfield_size;
1243 buf += mfield_size;
1244 } else {
1245 mfield_size = 0;
1246 MM_DBG("continuous buffer\n");
1247 }
1248 frame->mfield_sz = mfield_size;
1249 }
1250 MM_DBG("copying the stream count = %d\n", count);
1251 if (copy_from_user(cpy_ptr, buf, count)) {
1252 rc = -EFAULT;
1253 goto error;
1254 }
1255exit:
1256 frame->used = count;
1257 audio->out_head ^= 1;
1258 if (!audio->flush_ack)
1259 audpreproc_pcm_send_data(audio, 0);
1260 else {
1261 audpreproc_pcm_send_data(audio, 1);
1262 audio->flush_ack = 0;
1263 }
1264 if (eos_condition == AUDPREPROC_AAC_EOS_SET)
1265 rc = audpreproc_aac_process_eos(audio, start, mfield_size);
1266 mutex_unlock(&audio->write_lock);
1267 return write_count;
1268error:
1269 mutex_unlock(&audio->write_lock);
1270 return rc;
1271}
1272
1273static int audaac_in_release(struct inode *inode, struct file *file)
1274{
1275 struct audio_in *audio = file->private_data;
1276
1277 mutex_lock(&audio->lock);
1278 /* with draw frequency for session
1279 incase not stopped the driver */
1280 msm_snddev_withdraw_freq(audio->enc_id, SNDDEV_CAP_TX,
1281 AUDDEV_CLNT_ENC);
1282 auddev_unregister_evt_listner(AUDDEV_CLNT_ENC, audio->enc_id);
1283 /*reset the sampling frequency information at audpreproc layer*/
1284 audio->session_info.sampling_freq = 0;
1285 audpreproc_update_audrec_info(&audio->session_info);
1286 audaac_in_disable(audio);
1287 audaac_in_flush(audio);
1288 msm_adsp_put(audio->audrec);
1289 audpreproc_aenc_free(audio->enc_id);
1290 audio->audrec = NULL;
1291 audio->opened = 0;
1292 if (audio->data) {
Laura Abbott61399692012-04-30 14:25:46 -07001293 iounmap(audio->map_v_read);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301294 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001295 audio->data = NULL;
1296 }
1297 if (audio->out_data) {
Laura Abbott61399692012-04-30 14:25:46 -07001298 iounmap(audio->map_v_write);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301299 free_contiguous_memory_by_paddr(audio->out_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001300 audio->out_data = NULL;
1301 }
1302 mutex_unlock(&audio->lock);
1303 return 0;
1304}
1305
1306struct audio_in the_audio_aac_in;
1307
1308static int audaac_in_open(struct inode *inode, struct file *file)
1309{
1310 struct audio_in *audio = &the_audio_aac_in;
1311 int rc;
1312 int encid;
1313
1314 mutex_lock(&audio->lock);
1315 if (audio->opened) {
1316 rc = -EBUSY;
1317 goto done;
1318 }
Santosh Mardifdc227a2011-07-11 17:20:34 +05301319 audio->phys = allocate_contiguous_ebi_nomap(DMASZ, SZ_4K);
1320 if (audio->phys) {
Laura Abbott61399692012-04-30 14:25:46 -07001321 audio->map_v_read = ioremap(audio->phys, DMASZ);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301322 if (IS_ERR(audio->map_v_read)) {
1323 MM_ERR("could not map DMA buffers\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001324 rc = -ENOMEM;
Santosh Mardifdc227a2011-07-11 17:20:34 +05301325 free_contiguous_memory_by_paddr(audio->phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001326 goto done;
1327 }
Laura Abbott61399692012-04-30 14:25:46 -07001328 audio->data = audio->map_v_read;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001329 } else {
1330 MM_ERR("could not allocate DMA buffers\n");
1331 rc = -ENOMEM;
1332 goto done;
1333 }
1334 MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x\n",\
1335 (int) audio->data, (int) audio->phys);
1336 if ((file->f_mode & FMODE_WRITE) &&
1337 (file->f_mode & FMODE_READ)) {
1338 audio->mode = MSM_AUD_ENC_MODE_NONTUNNEL;
1339 } else if (!(file->f_mode & FMODE_WRITE) &&
1340 (file->f_mode & FMODE_READ)) {
1341 audio->mode = MSM_AUD_ENC_MODE_TUNNEL;
1342 MM_DBG("Opened for tunnel mode encoding\n");
1343 } else {
1344 rc = -EACCES;
1345 goto done;
1346 }
1347
1348 /* Settings will be re-config at AUDIO_SET_CONFIG,
1349 * but at least we need to have initial config
1350 */
1351 if (audio->mode == MSM_AUD_ENC_MODE_NONTUNNEL)
1352 audio->buffer_size = (NT_FRAME_SIZE - 24);
1353 else
1354 audio->buffer_size = (FRAME_SIZE - 8);
1355 audio->enc_type = ENC_TYPE_AAC | audio->mode;
1356 audio->samp_rate = 8000;
1357 audio->channel_mode = AUDREC_CMD_MODE_MONO;
1358 /* For AAC, bit rate hard coded, default settings is
1359 * sample rate (8000) x channel count (1) x recording quality (1.75)
1360 * = 14000 bps */
1361 audio->bit_rate = 14000;
1362 audio->record_quality = 0x1c00;
1363 MM_DBG("enc_type = %x\n", audio->enc_type);
1364 encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name,
1365 &audio->queue_ids);
1366 if (encid < 0) {
1367 MM_ERR("No free encoder available\n");
1368 rc = -ENODEV;
1369 goto done;
1370 }
1371 audio->enc_id = encid;
1372
1373 rc = msm_adsp_get(audio->module_name, &audio->audrec,
1374 &audrec_aac_adsp_ops, audio);
1375
1376 if (rc) {
1377 audpreproc_aenc_free(audio->enc_id);
1378 goto done;
1379 }
1380
1381 audio->stopped = 0;
1382 audio->source = 0;
1383 audio->abort = 0;
1384 audio->wflush = 0;
1385 audio->rflush = 0;
1386 audio->flush_ack = 0;
1387
1388 audaac_in_flush(audio);
1389 audaac_out_flush(audio);
1390
Santosh Mardifdc227a2011-07-11 17:20:34 +05301391 audio->out_phys = allocate_contiguous_ebi_nomap(BUFFER_SIZE, SZ_4K);
1392 if (!audio->out_phys) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001393 MM_ERR("could not allocate write buffers\n");
1394 rc = -ENOMEM;
1395 goto evt_error;
1396 } else {
Laura Abbott61399692012-04-30 14:25:46 -07001397 audio->map_v_write = ioremap(
1398 audio->out_phys, BUFFER_SIZE);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301399 if (IS_ERR(audio->map_v_write)) {
1400 MM_ERR("could not map write phys address\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001401 rc = -ENOMEM;
Santosh Mardifdc227a2011-07-11 17:20:34 +05301402 free_contiguous_memory_by_paddr(audio->out_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001403 goto evt_error;
1404 }
Laura Abbott61399692012-04-30 14:25:46 -07001405 audio->out_data = audio->map_v_write;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001406 MM_DBG("write buf: phy addr 0x%08x kernel addr 0x%08x\n",
1407 audio->out_phys, (int)audio->out_data);
1408 }
Kalyani polepeddy7413d2b2011-10-14 15:42:15 +05301409 audio->build_id = socinfo_get_build_id();
Vinay Vaka4ff52a62011-12-13 15:38:35 +05301410 MM_DBG("Modem build id = %s\n", audio->build_id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001411
1412 /* Initialize buffer */
1413 audio->out[0].data = audio->out_data + 0;
1414 audio->out[0].addr = audio->out_phys + 0;
1415 audio->out[0].size = OUT_BUFFER_SIZE;
1416
1417 audio->out[1].data = audio->out_data + OUT_BUFFER_SIZE;
1418 audio->out[1].addr = audio->out_phys + OUT_BUFFER_SIZE;
1419 audio->out[1].size = OUT_BUFFER_SIZE;
1420
1421 MM_DBG("audio->out[0].data = %d audio->out[1].data = %d",
1422 (unsigned int)audio->out[0].data,
1423 (unsigned int)audio->out[1].data);
1424 audio->device_events = AUDDEV_EVT_DEV_RDY | AUDDEV_EVT_DEV_RLS |
1425 AUDDEV_EVT_FREQ_CHG;
1426
1427 rc = auddev_register_evt_listner(audio->device_events,
1428 AUDDEV_CLNT_ENC, audio->enc_id,
1429 aac_in_listener, (void *) audio);
1430 if (rc) {
1431 MM_ERR("failed to register device event listener\n");
Laura Abbott61399692012-04-30 14:25:46 -07001432 iounmap(audio->map_v_write);
Santosh Mardifdc227a2011-07-11 17:20:34 +05301433 free_contiguous_memory_by_paddr(audio->out_phys);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001434 goto evt_error;
1435 }
1436 audio->mfield = META_OUT_SIZE;
1437 file->private_data = audio;
1438 audio->opened = 1;
1439 audio->out_frame_cnt++;
1440 rc = 0;
1441done:
1442 mutex_unlock(&audio->lock);
1443 return rc;
1444evt_error:
1445 msm_adsp_put(audio->audrec);
1446 audpreproc_aenc_free(audio->enc_id);
1447 mutex_unlock(&audio->lock);
1448 return rc;
1449}
1450
1451static const struct file_operations audio_in_fops = {
1452 .owner = THIS_MODULE,
1453 .open = audaac_in_open,
1454 .release = audaac_in_release,
1455 .read = audaac_in_read,
1456 .write = audaac_in_write,
1457 .fsync = audaac_in_fsync,
1458 .unlocked_ioctl = audaac_in_ioctl,
1459};
1460
1461struct miscdevice audio_aac_in_misc = {
1462 .minor = MISC_DYNAMIC_MINOR,
1463 .name = "msm_aac_in",
1464 .fops = &audio_in_fops,
1465};
1466
1467static int __init audaac_in_init(void)
1468{
1469 mutex_init(&the_audio_aac_in.lock);
1470 mutex_init(&the_audio_aac_in.read_lock);
1471 spin_lock_init(&the_audio_aac_in.dsp_lock);
1472 spin_lock_init(&the_audio_aac_in.dev_lock);
1473 init_waitqueue_head(&the_audio_aac_in.wait);
1474 init_waitqueue_head(&the_audio_aac_in.wait_enable);
1475 mutex_init(&the_audio_aac_in.write_lock);
1476 init_waitqueue_head(&the_audio_aac_in.write_wait);
1477
1478 return misc_register(&audio_aac_in_misc);
1479}
1480
1481device_initcall(audaac_in_init);