/arch/arm/mach-msm/qdsp5v2/audio_a2dp_in.c
C | 945 lines | 779 code | 100 blank | 66 comment | 104 complexity | 4a5a0248fb0f38b6421554afa8b01647 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
1/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * sbc/pcm audio input driver
4 * Based on the pcm input driver in arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c
5 *
6 * Copyright (C) 2008 HTC Corporation
7 * Copyright (C) 2008 Google, Inc.
8 *
9 * All source code in this file is licensed under the following license except
10 * where indicated.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License version 2 as published
14 * by the Free Software Foundation.
15 *
16 * This software is licensed under the terms of the GNU General Public
17 * License version 2, as published by the Free Software Foundation, and
18 * may be copied, distributed, and modified under those terms.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 */
26#include <linux/module.h>
27#include <linux/fs.h>
28#include <linux/miscdevice.h>
29#include <linux/uaccess.h>
30#include <linux/sched.h>
31#include <linux/wait.h>
32#include <linux/dma-mapping.h>
33#include <linux/msm_audio.h>
34#include <linux/msm_audio_sbc.h>
35#include <asm/atomic.h>
36#include <asm/ioctls.h>
37
38#include <mach/msm_adsp.h>
39#include <mach/qdsp5v2/qdsp5audreccmdi.h>
40#include <mach/qdsp5v2/qdsp5audrecmsg.h>
41#include <mach/qdsp5v2/audpreproc.h>
42#include <mach/qdsp5v2/audio_dev_ctl.h>
43#include <mach/debug_mm.h>
44
45/* FRAME_NUM must be a power of two */
46#define FRAME_NUM (8)
47#define FRAME_SIZE (2052 * 2)
48#define FRAME_SIZE_SBC (768 * 2)
49#define MONO_DATA_SIZE (2048)
50#define STEREO_DATA_SIZE (MONO_DATA_SIZE * 2)
51#define DMASZ (FRAME_SIZE * FRAME_NUM)
52
53struct buffer {
54 void *data;
55 uint32_t size;
56 uint32_t read;
57 uint32_t addr;
58 uint32_t frame_num;
59 uint32_t frame_len;
60};
61
62struct audio_a2dp_in {
63 struct buffer in[FRAME_NUM];
64
65 spinlock_t dsp_lock;
66
67 atomic_t in_bytes;
68 atomic_t in_samples;
69
70 struct mutex lock;
71 struct mutex read_lock;
72 wait_queue_head_t wait;
73 wait_queue_head_t wait_enable;
74
75 struct msm_adsp_module *audrec;
76
77 /* configuration to use on next enable */
78 uint32_t samp_rate;
79 uint32_t channel_mode;
80 uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */
81 uint32_t enc_type;
82 struct msm_audio_sbc_enc_config cfg;
83
84 uint32_t dsp_cnt;
85 uint32_t in_head; /* next buffer dsp will write */
86 uint32_t in_tail; /* next buffer read() will read */
87 uint32_t in_count; /* number of buffers available to read() */
88 uint32_t mode;
89
90 const char *module_name;
91 unsigned queue_ids;
92 uint16_t enc_id; /* Session Id */
93
94 uint16_t source; /* Encoding source bit mask */
95 uint32_t device_events; /* device events interested in */
96 uint32_t dev_cnt;
97 spinlock_t dev_lock;
98
99 /* data allocated for various buffers */
100 char *data;
101 dma_addr_t phys;
102
103 int opened;
104 int enabled;
105 int running;
106 int stopped; /* set when stopped, cleared on flush */
107 int abort; /* set when error, like sample rate mismatch */
108};
109
110static struct audio_a2dp_in the_audio_a2dp_in;
111
112struct wav_frame {
113 uint16_t frame_count_lsw;
114 uint16_t frame_count_msw;
115 uint16_t frame_length;
116 uint16_t erased_a2dp;
117 unsigned char raw_bitstream[]; /* samples */
118};
119
120struct sbc_frame {
121 uint16_t bit_rate_msw;
122 uint16_t bit_rate_lsw;
123 uint16_t frame_length;
124 uint16_t frame_num;
125 unsigned char raw_bitstream[]; /* samples */
126};
127
128struct audio_frame {
129 union {
130 struct wav_frame wav;
131 struct sbc_frame sbc;
132 } a2dp;
133} __attribute__((packed));
134
135/* Audrec Queue command sent macro's */
136#define audrec_send_bitstreamqueue(audio, cmd, len) \
137 msm_adsp_write(audio->audrec, ((audio->queue_ids & 0xFFFF0000) >> 16),\
138 cmd, len)
139
140#define audrec_send_audrecqueue(audio, cmd, len) \
141 msm_adsp_write(audio->audrec, (audio->queue_ids & 0x0000FFFF),\
142 cmd, len)
143
144/* DSP command send functions */
145static int auda2dp_in_enc_config(struct audio_a2dp_in *audio, int enable);
146static int auda2dp_in_param_config(struct audio_a2dp_in *audio);
147static int auda2dp_in_mem_config(struct audio_a2dp_in *audio);
148static int auda2dp_in_record_config(struct audio_a2dp_in *audio, int enable);
149static int auda2dp_dsp_read_buffer(struct audio_a2dp_in *audio,
150 uint32_t read_cnt);
151
152static void auda2dp_in_get_dsp_frames(struct audio_a2dp_in *audio);
153
154static void auda2dp_in_flush(struct audio_a2dp_in *audio);
155
156static void a2dp_in_listener(u32 evt_id, union auddev_evt_data *evt_payload,
157 void *private_data)
158{
159 struct audio_a2dp_in *audio = (struct audio_a2dp_in *) private_data;
160 unsigned long flags;
161
162 MM_DBG("evt_id = 0x%8x\n", evt_id);
163 switch (evt_id) {
164 case AUDDEV_EVT_DEV_RDY: {
165 MM_DBG("AUDDEV_EVT_DEV_RDY\n");
166 spin_lock_irqsave(&audio->dev_lock, flags);
167 audio->dev_cnt++;
168 audio->source |= (0x1 << evt_payload->routing_id);
169 spin_unlock_irqrestore(&audio->dev_lock, flags);
170
171 if ((audio->running == 1) && (audio->enabled == 1))
172 auda2dp_in_record_config(audio, 1);
173
174 break;
175 }
176 case AUDDEV_EVT_DEV_RLS: {
177 MM_DBG("AUDDEV_EVT_DEV_RLS\n");
178 spin_lock_irqsave(&audio->dev_lock, flags);
179 audio->dev_cnt--;
180 audio->source &= ~(0x1 << evt_payload->routing_id);
181 spin_unlock_irqrestore(&audio->dev_lock, flags);
182
183 if (!audio->running || !audio->enabled)
184 break;
185
186 /* Turn of as per source */
187 if (audio->source)
188 auda2dp_in_record_config(audio, 1);
189 else
190 /* Turn off all */
191 auda2dp_in_record_config(audio, 0);
192
193 break;
194 }
195 case AUDDEV_EVT_FREQ_CHG: {
196 MM_DBG("Encoder Driver got sample rate change event\n");
197 MM_DBG("sample rate %d\n", evt_payload->freq_info.sample_rate);
198 MM_DBG("dev_type %d\n", evt_payload->freq_info.dev_type);
199 MM_DBG("acdb_dev_id %d\n", evt_payload->freq_info.acdb_dev_id);
200 if (audio->running == 1) {
201 /* Stop Recording sample rate does not match
202 with device sample rate */
203 if (evt_payload->freq_info.sample_rate !=
204 audio->samp_rate) {
205 auda2dp_in_record_config(audio, 0);
206 audio->abort = 1;
207 wake_up(&audio->wait);
208 }
209 }
210 break;
211 }
212 default:
213 MM_ERR("wrong event %d\n", evt_id);
214 break;
215 }
216}
217
218/* ------------------- dsp preproc event handler--------------------- */
219static void audpreproc_dsp_event(void *data, unsigned id, void *msg)
220{
221 struct audio_a2dp_in *audio = data;
222
223 switch (id) {
224 case AUDPREPROC_ERROR_MSG: {
225 struct audpreproc_err_msg *err_msg = msg;
226
227 MM_ERR("ERROR_MSG: stream id %d err idx %d\n",
228 err_msg->stream_id, err_msg->aud_preproc_err_idx);
229 /* Error case */
230 wake_up(&audio->wait_enable);
231 break;
232 }
233 case AUDPREPROC_CMD_CFG_DONE_MSG: {
234 MM_DBG("CMD_CFG_DONE_MSG \n");
235 break;
236 }
237 case AUDPREPROC_CMD_ENC_CFG_DONE_MSG: {
238 struct audpreproc_cmd_enc_cfg_done_msg *enc_cfg_msg = msg;
239
240 MM_DBG("CMD_ENC_CFG_DONE_MSG: stream id %d enc type \
241 0x%8x\n", enc_cfg_msg->stream_id,
242 enc_cfg_msg->rec_enc_type);
243 /* Encoder enable success */
244 if (enc_cfg_msg->rec_enc_type & ENCODE_ENABLE)
245 auda2dp_in_param_config(audio);
246 else { /* Encoder disable success */
247 audio->running = 0;
248 auda2dp_in_record_config(audio, 0);
249 }
250 break;
251 }
252 case AUDPREPROC_CMD_ENC_PARAM_CFG_DONE_MSG: {
253 MM_DBG("CMD_ENC_PARAM_CFG_DONE_MSG \n");
254 auda2dp_in_mem_config(audio);
255 break;
256 }
257 case AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG: {
258 MM_DBG("AFE_CMD_AUDIO_RECORD_CFG_DONE_MSG \n");
259 wake_up(&audio->wait_enable);
260 break;
261 }
262 default:
263 MM_ERR("Unknown Event id %d\n", id);
264 }
265}
266
267/* ------------------- dsp audrec event handler--------------------- */
268static void audrec_dsp_event(void *data, unsigned id, size_t len,
269 void (*getevent)(void *ptr, size_t len))
270{
271 struct audio_a2dp_in *audio = data;
272
273 switch (id) {
274 case AUDREC_CMD_MEM_CFG_DONE_MSG: {
275 MM_DBG("CMD_MEM_CFG_DONE MSG DONE\n");
276 audio->running = 1;
277 if (audio->dev_cnt > 0)
278 auda2dp_in_record_config(audio, 1);
279 break;
280 }
281 case AUDREC_FATAL_ERR_MSG: {
282 struct audrec_fatal_err_msg fatal_err_msg;
283
284 getevent(&fatal_err_msg, AUDREC_FATAL_ERR_MSG_LEN);
285 MM_ERR("FATAL_ERR_MSG: err id %d\n",
286 fatal_err_msg.audrec_err_id);
287 /* Error stop the encoder */
288 audio->stopped = 1;
289 wake_up(&audio->wait);
290 break;
291 }
292 case AUDREC_UP_PACKET_READY_MSG: {
293 struct audrec_up_pkt_ready_msg pkt_ready_msg;
294
295 getevent(&pkt_ready_msg, AUDREC_UP_PACKET_READY_MSG_LEN);
296 MM_DBG("UP_PACKET_READY_MSG: write cnt lsw %d \
297 write cnt msw %d read cnt lsw %d read cnt msw %d \n",\
298 pkt_ready_msg.audrec_packet_write_cnt_lsw, \
299 pkt_ready_msg.audrec_packet_write_cnt_msw, \
300 pkt_ready_msg.audrec_up_prev_read_cnt_lsw, \
301 pkt_ready_msg.audrec_up_prev_read_cnt_msw);
302
303 auda2dp_in_get_dsp_frames(audio);
304 break;
305 }
306 default:
307 MM_ERR("Unknown Event id %d\n", id);
308 }
309}
310
311static void auda2dp_in_get_dsp_frames(struct audio_a2dp_in *audio)
312{
313 struct audio_frame *frame;
314 uint32_t index;
315 unsigned long flags;
316
317 index = audio->in_head;
318
319 frame = (void *) (((char *)audio->in[index].data) - \
320 sizeof(*frame));
321
322 spin_lock_irqsave(&audio->dsp_lock, flags);
323 if (audio->enc_type == ENC_TYPE_WAV)
324 audio->in[index].size = frame->a2dp.wav.frame_length;
325 else if (audio->enc_type == ENC_TYPE_SBC) {
326 audio->in[index].size = frame->a2dp.sbc.frame_length *
327 frame->a2dp.sbc.frame_num;
328 audio->in[index].frame_num = frame->a2dp.sbc.frame_num;
329 audio->in[index].frame_len = frame->a2dp.sbc.frame_length;
330 }
331
332 /* statistics of read */
333 atomic_add(audio->in[index].size, &audio->in_bytes);
334 atomic_add(1, &audio->in_samples);
335
336 audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1);
337
338 /* If overflow, move the tail index foward. */
339 if (audio->in_head == audio->in_tail)
340 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
341 else
342 audio->in_count++;
343
344 auda2dp_dsp_read_buffer(audio, audio->dsp_cnt++);
345 spin_unlock_irqrestore(&audio->dsp_lock, flags);
346 wake_up(&audio->wait);
347}
348
349static struct msm_adsp_ops audrec_adsp_ops = {
350 .event = audrec_dsp_event,
351};
352
353static int auda2dp_in_enc_config(struct audio_a2dp_in *audio, int enable)
354{
355 struct audpreproc_audrec_cmd_enc_cfg cmd;
356
357 memset(&cmd, 0, sizeof(cmd));
358 cmd.cmd_id = AUDPREPROC_AUDREC_CMD_ENC_CFG;
359 cmd.stream_id = audio->enc_id;
360
361 if (enable)
362 cmd.audrec_enc_type = audio->enc_type | ENCODE_ENABLE;
363 else
364 cmd.audrec_enc_type &= ~(ENCODE_ENABLE);
365
366 return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd));
367}
368
369static int auda2dp_in_param_config(struct audio_a2dp_in *audio)
370{
371 if (audio->enc_type == ENC_TYPE_WAV) {
372 struct audpreproc_audrec_cmd_parm_cfg_wav cmd;
373
374 memset(&cmd, 0, sizeof(cmd));
375 cmd.common.cmd_id = AUDPREPROC_AUDREC_CMD_PARAM_CFG;
376 cmd.common.stream_id = audio->enc_id;
377
378 cmd.aud_rec_samplerate_idx = audio->samp_rate;
379 cmd.aud_rec_stereo_mode = audio->channel_mode;
380 return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd));
381 } else if (audio->enc_type == ENC_TYPE_SBC) {
382 struct audpreproc_audrec_cmd_parm_cfg_sbc cmd;
383
384 memset(&cmd, 0, sizeof(cmd));
385 cmd.common.cmd_id = AUDPREPROC_AUDREC_CMD_PARAM_CFG;
386 cmd.common.stream_id = audio->enc_id;
387 cmd.aud_rec_sbc_enc_param =
388 (audio->cfg.number_of_blocks <<
389 AUDREC_SBC_ENC_PARAM_NUM_SUB_BLOCKS_MASK) |
390 (audio->cfg.number_of_subbands <<
391 AUDREC_SBC_ENC_PARAM_NUM_SUB_BANDS_MASK) |
392 (audio->cfg.mode <<
393 AUDREC_SBC_ENC_PARAM_MODE_MASK) |
394 (audio->cfg.bit_allocation <<
395 AUDREC_SBC_ENC_PARAM_BIT_ALLOC_MASK);
396 cmd.aud_rec_sbc_bit_rate_msw =
397 (audio->cfg.bit_rate & 0xFFFF0000) >> 16;
398 cmd.aud_rec_sbc_bit_rate_lsw =
399 (audio->cfg.bit_rate & 0xFFFF);
400 return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd));
401 }
402 return 0;
403}
404
405/* To Do: msm_snddev_route_enc(audio->enc_id); */
406static int auda2dp_in_record_config(struct audio_a2dp_in *audio, int enable)
407{
408 struct audpreproc_afe_cmd_audio_record_cfg cmd;
409
410 memset(&cmd, 0, sizeof(cmd));
411 cmd.cmd_id = AUDPREPROC_AFE_CMD_AUDIO_RECORD_CFG;
412 cmd.stream_id = audio->enc_id;
413 if (enable)
414 cmd.destination_activity = AUDIO_RECORDING_TURN_ON;
415 else
416 cmd.destination_activity = AUDIO_RECORDING_TURN_OFF;
417
418 cmd.source_mix_mask = audio->source;
419 if (audio->enc_id == 2) {
420 if ((cmd.source_mix_mask &
421 INTERNAL_CODEC_TX_SOURCE_MIX_MASK) ||
422 (cmd.source_mix_mask & AUX_CODEC_TX_SOURCE_MIX_MASK) ||
423 (cmd.source_mix_mask & VOICE_UL_SOURCE_MIX_MASK) ||
424 (cmd.source_mix_mask & VOICE_DL_SOURCE_MIX_MASK)) {
425 cmd.pipe_id = SOURCE_PIPE_1;
426 }
427 if (cmd.source_mix_mask &
428 AUDPP_A2DP_PIPE_SOURCE_MIX_MASK)
429 cmd.pipe_id |= SOURCE_PIPE_0;
430 }
431 return audpreproc_send_audreccmdqueue(&cmd, sizeof(cmd));
432}
433
434static int auda2dp_in_mem_config(struct audio_a2dp_in *audio)
435{
436 struct audrec_cmd_arecmem_cfg cmd;
437 uint16_t *data = (void *) audio->data;
438 int n;
439
440 memset(&cmd, 0, sizeof(cmd));
441 cmd.cmd_id = AUDREC_CMD_MEM_CFG_CMD;
442 cmd.audrec_up_pkt_intm_count = 1;
443 cmd.audrec_ext_pkt_start_addr_msw = audio->phys >> 16;
444 cmd.audrec_ext_pkt_start_addr_lsw = audio->phys;
445 cmd.audrec_ext_pkt_buf_number = FRAME_NUM;
446
447 /* prepare buffer pointers:
448 * Wav:
449 * Mono: 1024 samples + 4 halfword header
450 * Stereo: 2048 samples + 4 halfword header
451 * SBC:
452 * 768 + 4 halfword header
453 */
454 if (audio->enc_type == ENC_TYPE_SBC) {
455 for (n = 0; n < FRAME_NUM; n++) {
456 audio->in[n].data = data + 4;
457 data += (4 + (FRAME_SIZE_SBC/2));
458 MM_DBG("0x%8x\n", (int)(audio->in[n].data - 8));
459 }
460 } else if (audio->enc_type == ENC_TYPE_WAV) {
461 for (n = 0; n < FRAME_NUM; n++) {
462 audio->in[n].data = data + 4;
463 data += (4 + (audio->channel_mode ? 2048 : 1024));
464 MM_DBG("0x%8x\n", (int)(audio->in[n].data - 8));
465 }
466 }
467
468 return audrec_send_audrecqueue(audio, &cmd, sizeof(cmd));
469}
470
471static int auda2dp_dsp_read_buffer(struct audio_a2dp_in *audio,
472 uint32_t read_cnt)
473{
474 struct up_audrec_packet_ext_ptr cmd;
475
476 memset(&cmd, 0, sizeof(cmd));
477 cmd.cmd_id = UP_AUDREC_PACKET_EXT_PTR;
478 cmd.audrec_up_curr_read_count_msw = read_cnt >> 16;
479 cmd.audrec_up_curr_read_count_lsw = read_cnt;
480
481 return audrec_send_bitstreamqueue(audio, &cmd, sizeof(cmd));
482}
483
484/* must be called with audio->lock held */
485static int auda2dp_in_enable(struct audio_a2dp_in *audio)
486{
487 if (audio->enabled)
488 return 0;
489
490 if (audpreproc_enable(audio->enc_id, &audpreproc_dsp_event, audio)) {
491 MM_ERR("msm_adsp_enable(audpreproc) failed\n");
492 return -ENODEV;
493 }
494
495 if (msm_adsp_enable(audio->audrec)) {
496 MM_ERR("msm_adsp_enable(audrec) failed\n");
497 audpreproc_disable(audio->enc_id, audio);
498 return -ENODEV;
499 }
500 audio->enabled = 1;
501 auda2dp_in_enc_config(audio, 1);
502
503 return 0;
504}
505
506/* must be called with audio->lock held */
507static int auda2dp_in_disable(struct audio_a2dp_in *audio)
508{
509 if (audio->enabled) {
510 audio->enabled = 0;
511 auda2dp_in_enc_config(audio, 0);
512 wake_up(&audio->wait);
513 wait_event_interruptible_timeout(audio->wait_enable,
514 audio->running == 0, 1*HZ);
515 msm_adsp_disable(audio->audrec);
516 audpreproc_disable(audio->enc_id, audio);
517 }
518 return 0;
519}
520
521static void auda2dp_in_flush(struct audio_a2dp_in *audio)
522{
523 int i;
524
525 audio->dsp_cnt = 0;
526 audio->in_head = 0;
527 audio->in_tail = 0;
528 audio->in_count = 0;
529 for (i = 0; i < FRAME_NUM; i++) {
530 audio->in[i].size = 0;
531 audio->in[i].read = 0;
532 }
533 MM_DBG("in_bytes %d\n", atomic_read(&audio->in_bytes));
534 MM_DBG("in_samples %d\n", atomic_read(&audio->in_samples));
535 atomic_set(&audio->in_bytes, 0);
536 atomic_set(&audio->in_samples, 0);
537}
538
539/* ------------------- device --------------------- */
540static long auda2dp_in_ioctl(struct file *file,
541 unsigned int cmd, unsigned long arg)
542{
543 struct audio_a2dp_in *audio = file->private_data;
544 int rc = 0;
545
546 if (cmd == AUDIO_GET_STATS) {
547 struct msm_audio_stats stats;
548 stats.byte_count = atomic_read(&audio->in_bytes);
549 stats.sample_count = atomic_read(&audio->in_samples);
550 if (copy_to_user((void *) arg, &stats, sizeof(stats)))
551 return -EFAULT;
552 return rc;
553 }
554
555 mutex_lock(&audio->lock);
556 switch (cmd) {
557 case AUDIO_START: {
558 uint32_t freq;
559 /* Poll at 48KHz always */
560 freq = 48000;
561 MM_DBG("AUDIO_START\n");
562 rc = msm_snddev_request_freq(&freq, audio->enc_id,
563 SNDDEV_CAP_TX, AUDDEV_CLNT_ENC);
564 MM_DBG("sample rate configured %d sample rate requested %d\n",
565 freq, audio->samp_rate);
566 if (rc < 0) {
567 MM_DBG("sample rate can not be set, return code %d\n",\
568 rc);
569 msm_snddev_withdraw_freq(audio->enc_id,
570 SNDDEV_CAP_TX, AUDDEV_CLNT_ENC);
571 MM_DBG("msm_snddev_withdraw_freq\n");
572 break;
573 }
574 rc = auda2dp_in_enable(audio);
575 if (!rc) {
576 rc =
577 wait_event_interruptible_timeout(audio->wait_enable,
578 audio->running != 0, 1*HZ);
579 MM_DBG("state %d rc = %d\n", audio->running, rc);
580
581 if (audio->running == 0) {
582 rc = -ENODEV;
583 msm_snddev_withdraw_freq(audio->enc_id,
584 SNDDEV_CAP_TX, AUDDEV_CLNT_ENC);
585 MM_DBG("msm_snddev_withdraw_freq\n");
586 } else
587 rc = 0;
588 }
589 audio->stopped = 0;
590 break;
591 }
592 case AUDIO_STOP: {
593 rc = auda2dp_in_disable(audio);
594 rc = msm_snddev_withdraw_freq(audio->enc_id,
595 SNDDEV_CAP_TX, AUDDEV_CLNT_ENC);
596 MM_DBG("msm_snddev_withdraw_freq\n");
597 audio->stopped = 1;
598 audio->abort = 0;
599 break;
600 }
601 case AUDIO_FLUSH: {
602 if (audio->stopped) {
603 /* Make sure we're stopped and we wake any threads
604 * that might be blocked holding the read_lock.
605 * While audio->stopped read threads will always
606 * exit immediately.
607 */
608 wake_up(&audio->wait);
609 mutex_lock(&audio->read_lock);
610 auda2dp_in_flush(audio);
611 mutex_unlock(&audio->read_lock);
612 }
613 break;
614 }
615 case AUDIO_SET_STREAM_CONFIG: {
616 struct msm_audio_stream_config cfg;
617 if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
618 rc = -EFAULT;
619 break;
620 }
621 /* Allow only single frame */
622 if ((audio->enc_type == ENC_TYPE_SBC) &&
623 (cfg.buffer_size != FRAME_SIZE_SBC))
624 rc = -EINVAL;
625 else
626 audio->buffer_size = cfg.buffer_size;
627 break;
628 }
629 case AUDIO_GET_STREAM_CONFIG: {
630 struct msm_audio_stream_config cfg;
631 memset(&cfg, 0, sizeof(cfg));
632 if (audio->enc_type == ENC_TYPE_SBC)
633 cfg.buffer_size = FRAME_SIZE_SBC;
634 else
635 cfg.buffer_size = MONO_DATA_SIZE;
636 cfg.buffer_count = FRAME_NUM;
637 if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
638 rc = -EFAULT;
639 break;
640 }
641 case AUDIO_SET_SBC_ENC_CONFIG: {
642 if (copy_from_user(&audio->cfg, (void *) arg,
643 sizeof(audio->cfg))) {
644 rc = -EFAULT;
645 break;
646 }
647 audio->samp_rate = audio->cfg.sample_rate;
648 audio->channel_mode = audio->cfg.channels;
649 audio->enc_type = ENC_TYPE_SBC;
650 break;
651 }
652 case AUDIO_SET_CONFIG: {
653 struct msm_audio_config cfg;
654 if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
655 rc = -EFAULT;
656 break;
657 }
658 if (cfg.channel_count == 1) {
659 cfg.channel_count = AUDREC_CMD_MODE_MONO;
660 audio->buffer_size = MONO_DATA_SIZE;
661 } else if (cfg.channel_count == 2) {
662 cfg.channel_count = AUDREC_CMD_MODE_STEREO;
663 audio->buffer_size = STEREO_DATA_SIZE;
664 } else {
665 rc = -EINVAL;
666 break;
667 }
668 audio->samp_rate = cfg.sample_rate;
669 audio->channel_mode = cfg.channel_count;
670 audio->enc_type = ENC_TYPE_WAV;
671 break;
672 }
673 case AUDIO_GET_SBC_ENC_CONFIG: {
674 struct msm_audio_sbc_enc_config cfg;
675 memset(&cfg, 0, sizeof(cfg));
676 cfg.bit_allocation = audio->cfg.bit_allocation;
677 cfg.mode = audio->cfg.mode;
678 cfg.number_of_subbands = audio->cfg.number_of_subbands;
679 cfg.number_of_blocks = audio->cfg.number_of_blocks;
680 cfg.sample_rate = audio->samp_rate;
681 cfg.channels = audio->channel_mode;
682 cfg.bit_rate = audio->cfg.bit_rate;
683 if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
684 rc = -EFAULT;
685 break;
686 }
687 case AUDIO_GET_CONFIG: {
688 struct msm_audio_config cfg;
689 memset(&cfg, 0, sizeof(cfg));
690 cfg.buffer_count = FRAME_NUM;
691 cfg.sample_rate = audio->samp_rate;
692 if (audio->channel_mode == AUDREC_CMD_MODE_MONO) {
693 cfg.channel_count = 1;
694 cfg.buffer_size = MONO_DATA_SIZE;
695 } else {
696 cfg.channel_count = 2;
697 cfg.buffer_size = STEREO_DATA_SIZE;
698 }
699 cfg.type = ENC_TYPE_WAV;
700 if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
701 rc = -EFAULT;
702 break;
703 }
704 case AUDIO_GET_SESSION_ID: {
705 if (copy_to_user((void *) arg, &audio->enc_id,
706 sizeof(unsigned short))) {
707 rc = -EFAULT;
708 }
709 break;
710 }
711 default:
712 rc = -EINVAL;
713 }
714 mutex_unlock(&audio->lock);
715 return rc;
716}
717
718static ssize_t auda2dp_in_read(struct file *file,
719 char __user *buf,
720 size_t count, loff_t *pos)
721{
722 struct audio_a2dp_in *audio = file->private_data;
723 unsigned long flags;
724 const char __user *start = buf;
725 void *data;
726 uint32_t index;
727 uint32_t size;
728 int rc = 0;
729 uint32_t f_len = 0, f_num = 0;
730 int i = 0;
731
732 mutex_lock(&audio->read_lock);
733 while (count > 0) {
734 rc = wait_event_interruptible(
735 audio->wait, (audio->in_count > 0) || audio->stopped ||
736 audio->abort);
737
738 if (rc < 0)
739 break;
740
741 if (audio->stopped && !audio->in_count) {
742 MM_DBG("Driver in stop state, No more buffer to read");
743 rc = 0;/* End of File */
744 break;
745 }
746
747 if (audio->abort) {
748 rc = -EPERM; /* Not permitted due to abort */
749 break;
750 }
751
752 index = audio->in_tail;
753 data = (uint8_t *) audio->in[index].data;
754 size = audio->in[index].size;
755 if (count >= size) {
756 if (audio->enc_type == ENC_TYPE_SBC &&
757 (audio->in[index].frame_len % 2)) {
758 f_len = audio->in[index].frame_len;
759 f_num = audio->in[index].frame_num;
760 for (i = 0; i < f_num; i++) {
761 if (copy_to_user(&buf[i * f_len],
762 (uint8_t *) (data + (i * (f_len + 1))),
763 f_len)) {
764 rc = -EFAULT;
765 break;
766 }
767 }
768 } else {
769 if (copy_to_user(buf, data, size)) {
770 rc = -EFAULT;
771 break;
772 }
773 }
774 spin_lock_irqsave(&audio->dsp_lock, flags);
775 if (index != audio->in_tail) {
776 /* overrun -- data is
777 * invalid and we need to retry */
778 spin_unlock_irqrestore(&audio->dsp_lock, flags);
779 continue;
780 }
781 audio->in[index].size = 0;
782 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
783 audio->in_count--;
784 spin_unlock_irqrestore(&audio->dsp_lock, flags);
785 count -= size;
786 buf += size;
787 } else {
788 MM_ERR("short read\n");
789 break;
790 }
791 }
792 mutex_unlock(&audio->read_lock);
793 if (buf > start)
794 return buf - start;
795
796 return rc;
797}
798
799static ssize_t auda2dp_in_write(struct file *file,
800 const char __user *buf,
801 size_t count, loff_t *pos)
802{
803 return -EINVAL;
804}
805
806static int auda2dp_in_release(struct inode *inode, struct file *file)
807{
808 struct audio_a2dp_in *audio = file->private_data;
809
810 mutex_lock(&audio->lock);
811 /* with draw frequency for session
812 incase not stopped the driver */
813 msm_snddev_withdraw_freq(audio->enc_id, SNDDEV_CAP_TX,
814 AUDDEV_CLNT_ENC);
815 auddev_unregister_evt_listner(AUDDEV_CLNT_ENC, audio->enc_id);
816 auda2dp_in_disable(audio);
817 auda2dp_in_flush(audio);
818 msm_adsp_put(audio->audrec);
819 audpreproc_aenc_free(audio->enc_id);
820 audio->audrec = NULL;
821 audio->opened = 0;
822 mutex_unlock(&audio->lock);
823 return 0;
824}
825
826static int auda2dp_in_open(struct inode *inode, struct file *file)
827{
828 struct audio_a2dp_in *audio = &the_audio_a2dp_in;
829 int rc;
830 int encid;
831
832 mutex_lock(&audio->lock);
833 if (audio->opened) {
834 rc = -EBUSY;
835 goto done;
836 }
837 if ((file->f_mode & FMODE_WRITE) &&
838 (file->f_mode & FMODE_READ)) {
839 rc = -EACCES;
840 MM_ERR("Non tunnel encoding is not supported\n");
841 goto done;
842 } else if (!(file->f_mode & FMODE_WRITE) &&
843 (file->f_mode & FMODE_READ)) {
844 audio->mode = MSM_AUD_ENC_MODE_TUNNEL;
845 MM_DBG("Opened for Tunnel mode encoding\n");
846 } else {
847 rc = -EACCES;
848 goto done;
849 }
850 /* Settings will be re-config at AUDIO_SET_CONFIG/SBC_ENC_CONFIG,
851 * but at least we need to have initial config
852 */
853 audio->channel_mode = AUDREC_CMD_MODE_MONO;
854 audio->buffer_size = FRAME_SIZE_SBC;
855 audio->samp_rate = 48000;
856 audio->enc_type = ENC_TYPE_SBC | audio->mode;
857 audio->cfg.bit_allocation = AUDIO_SBC_BA_SNR;
858 audio->cfg.mode = AUDIO_SBC_MODE_JSTEREO;
859 audio->cfg.number_of_subbands = AUDIO_SBC_BANDS_8;
860 audio->cfg.number_of_blocks = AUDIO_SBC_BLOCKS_16;
861 audio->cfg.bit_rate = 320000; /* max 512kbps(mono), 320kbs(others) */
862
863 encid = audpreproc_aenc_alloc(audio->enc_type, &audio->module_name,
864 &audio->queue_ids);
865 if (encid < 0) {
866 MM_ERR("No free encoder available\n");
867 rc = -ENODEV;
868 goto done;
869 }
870 audio->enc_id = encid;
871
872 rc = msm_adsp_get(audio->module_name, &audio->audrec,
873 &audrec_adsp_ops, audio);
874
875 if (rc) {
876 audpreproc_aenc_free(audio->enc_id);
877 goto done;
878 }
879
880 audio->stopped = 0;
881 audio->source = 0;
882 audio->abort = 0;
883 auda2dp_in_flush(audio);
884 audio->device_events = AUDDEV_EVT_DEV_RDY | AUDDEV_EVT_DEV_RLS |
885 AUDDEV_EVT_FREQ_CHG;
886
887 rc = auddev_register_evt_listner(audio->device_events,
888 AUDDEV_CLNT_ENC, audio->enc_id,
889 a2dp_in_listener, (void *) audio);
890 if (rc) {
891 MM_ERR("failed to register device event listener\n");
892 goto evt_error;
893 }
894 file->private_data = audio;
895 audio->opened = 1;
896 rc = 0;
897done:
898 mutex_unlock(&audio->lock);
899 return rc;
900evt_error:
901 msm_adsp_put(audio->audrec);
902 audpreproc_aenc_free(audio->enc_id);
903 mutex_unlock(&audio->lock);
904 return rc;
905}
906
907static const struct file_operations audio_a2dp_in_fops = {
908 .owner = THIS_MODULE,
909 .open = auda2dp_in_open,
910 .release = auda2dp_in_release,
911 .read = auda2dp_in_read,
912 .write = auda2dp_in_write,
913 .unlocked_ioctl = auda2dp_in_ioctl,
914};
915
916struct miscdevice audio_a2dp_in_misc = {
917 .minor = MISC_DYNAMIC_MINOR,
918 .name = "msm_a2dp_in",
919 .fops = &audio_a2dp_in_fops,
920};
921
922static int __init auda2dp_in_init(void)
923{
924 the_audio_a2dp_in.data = dma_alloc_coherent(NULL, DMASZ,
925 &the_audio_a2dp_in.phys, GFP_KERNEL);
926 MM_DBG("Memory addr = 0x%8x phy addr = 0x%8x ---- \n", \
927 (int) the_audio_a2dp_in.data, (int) the_audio_a2dp_in.phys);
928
929 if (!the_audio_a2dp_in.data) {
930 MM_ERR("Unable to allocate DMA buffer\n");
931 return -ENOMEM;
932 }
933 mutex_init(&the_audio_a2dp_in.lock);
934 mutex_init(&the_audio_a2dp_in.read_lock);
935 spin_lock_init(&the_audio_a2dp_in.dsp_lock);
936 spin_lock_init(&the_audio_a2dp_in.dev_lock);
937 init_waitqueue_head(&the_audio_a2dp_in.wait);
938 init_waitqueue_head(&the_audio_a2dp_in.wait_enable);
939 return misc_register(&audio_a2dp_in_misc);
940}
941
942device_initcall(auda2dp_in_init);
943
944MODULE_DESCRIPTION("MSM SBC encode driver");
945MODULE_LICENSE("GPL v2");