1/* arch/arm/mach-msm/qdsp5/audio_in.c 2 * 3 * pcm audio input device 4 * 5 * Copyright (C) 2008 Google, Inc. 6 * Copyright (C) 2008 HTC Corporation 7 * 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 19#include <linux/module.h> 20#include <linux/fs.h> 21#include <linux/miscdevice.h> 22#include <linux/uaccess.h> 23#include <linux/kthread.h> 24#include <linux/wait.h> 25#include <linux/dma-mapping.h> 26#include <linux/gfp.h> 27 28#include <linux/delay.h> 29 30#include <linux/msm_audio.h> 31 32#include <asm/atomic.h> 33#include <asm/ioctls.h> 34#include <mach/msm_adsp.h> 35#include <mach/msm_rpcrouter.h> 36 37#include "audmgr.h" 38 39#include <mach/qdsp5/qdsp5audpreproccmdi.h> 40#include <mach/qdsp5/qdsp5audpreprocmsg.h> 41#include <mach/qdsp5/qdsp5audreccmdi.h> 42#include <mach/qdsp5/qdsp5audrecmsg.h> 43 44/* for queue ids - should be relative to module number*/ 45#include "adsp.h" 46 47/* FRAME_NUM must be a power of two */ 48#define FRAME_NUM (8) 49#define FRAME_SIZE (2052 * 2) 50#define MONO_DATA_SIZE (2048) 51#define STEREO_DATA_SIZE (MONO_DATA_SIZE * 2) 52#define DMASZ (FRAME_SIZE * FRAME_NUM) 53 54#define AGC_PARAM_SIZE (20) 55#define NS_PARAM_SIZE (6) 56#define IIR_PARAM_SIZE (48) 57#define DEBUG (0) 58 59#define AGC_ENABLE 0x0001 60#define NS_ENABLE 0x0002 61#define IIR_ENABLE 0x0004 62 63struct tx_agc_config { 64 uint16_t agc_params[AGC_PARAM_SIZE]; 65}; 66 67struct ns_config { 68 uint16_t ns_params[NS_PARAM_SIZE]; 69}; 70 71struct tx_iir_filter { 72 uint16_t num_bands; 73 uint16_t iir_params[IIR_PARAM_SIZE]; 74}; 75 76struct audpre_cmd_iir_config_type { 77 uint16_t cmd_id; 78 uint16_t active_flag; 79 uint16_t num_bands; 80 uint16_t iir_params[IIR_PARAM_SIZE]; 81}; 82 83struct buffer { 84 void *data; 85 uint32_t size; 86 uint32_t read; 87 uint32_t addr; 88}; 89 90struct audio_in { 91 struct buffer in[FRAME_NUM]; 92 93 spinlock_t dsp_lock; 94 95 atomic_t in_bytes; 96 97 struct mutex lock; 98 struct mutex read_lock; 99 wait_queue_head_t wait; 100 101 struct msm_adsp_module *audpre; 102 struct msm_adsp_module *audrec; 103 104 /* configuration to use on next enable */ 105 uint32_t samp_rate; 106 uint32_t channel_mode; 107 uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */ 108 uint32_t type; /* 0 for PCM ,1 for AAC */ 109 uint32_t dsp_cnt; 110 uint32_t in_head; /* next buffer dsp will write */ 111 uint32_t in_tail; /* next buffer read() will read */ 112 uint32_t in_count; /* number of buffers available to read() */ 113 114 unsigned short samp_rate_index; 115 116 struct audmgr audmgr; 117 118 /* data allocated for various buffers */ 119 char *data; 120 dma_addr_t phys; 121 122 int opened; 123 int enabled; 124 int running; 125 int stopped; /* set when stopped, cleared on flush */ 126 127 /* audpre settings */ 128 int agc_enable; 129 struct tx_agc_config agc; 130 131 int ns_enable; 132 struct ns_config ns; 133 134 int iir_enable; 135 struct tx_iir_filter iir; 136}; 137 138static int audio_in_dsp_enable(struct audio_in *audio, int enable); 139static int audio_in_encoder_config(struct audio_in *audio); 140static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt); 141static void audio_flush(struct audio_in *audio); 142static int audio_dsp_set_agc(struct audio_in *audio); 143static int audio_dsp_set_ns(struct audio_in *audio); 144static int audio_dsp_set_tx_iir(struct audio_in *audio); 145 146static unsigned convert_dsp_samp_index(unsigned index) 147{ 148 switch (index) { 149 case 48000: return AUDREC_CMD_SAMP_RATE_INDX_48000; 150 case 44100: return AUDREC_CMD_SAMP_RATE_INDX_44100; 151 case 32000: return AUDREC_CMD_SAMP_RATE_INDX_32000; 152 case 24000: return AUDREC_CMD_SAMP_RATE_INDX_24000; 153 case 22050: return AUDREC_CMD_SAMP_RATE_INDX_22050; 154 case 16000: return AUDREC_CMD_SAMP_RATE_INDX_16000; 155 case 12000: return AUDREC_CMD_SAMP_RATE_INDX_12000; 156 case 11025: return AUDREC_CMD_SAMP_RATE_INDX_11025; 157 case 8000: return AUDREC_CMD_SAMP_RATE_INDX_8000; 158 default: return AUDREC_CMD_SAMP_RATE_INDX_11025; 159 } 160} 161 162static unsigned convert_samp_rate(unsigned hz) 163{ 164 switch (hz) { 165 case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000; 166 case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100; 167 case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000; 168 case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000; 169 case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050; 170 case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000; 171 case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000; 172 case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025; 173 case 8000: return RPC_AUD_DEF_SAMPLE_RATE_8000; 174 default: return RPC_AUD_DEF_SAMPLE_RATE_11025; 175 } 176} 177 178static unsigned convert_samp_index(unsigned index) 179{ 180 switch (index) { 181 case RPC_AUD_DEF_SAMPLE_RATE_48000: return 48000; 182 case RPC_AUD_DEF_SAMPLE_RATE_44100: return 44100; 183 case RPC_AUD_DEF_SAMPLE_RATE_32000: return 32000; 184 case RPC_AUD_DEF_SAMPLE_RATE_24000: return 24000; 185 case RPC_AUD_DEF_SAMPLE_RATE_22050: return 22050; 186 case RPC_AUD_DEF_SAMPLE_RATE_16000: return 16000; 187 case RPC_AUD_DEF_SAMPLE_RATE_12000: return 12000; 188 case RPC_AUD_DEF_SAMPLE_RATE_11025: return 11025; 189 case RPC_AUD_DEF_SAMPLE_RATE_8000: return 8000; 190 default: return 11025; 191 } 192} 193 194/* must be called with audio->lock held */ 195static int audio_in_enable(struct audio_in *audio) 196{ 197 struct audmgr_config cfg; 198 int rc; 199 200 if (audio->enabled) 201 return 0; 202 203 cfg.tx_rate = audio->samp_rate; 204 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; 205 cfg.def_method = RPC_AUD_DEF_METHOD_RECORD; 206 if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV) 207 cfg.codec = RPC_AUD_DEF_CODEC_PCM; 208 else 209 cfg.codec = RPC_AUD_DEF_CODEC_AAC; 210 cfg.snd_method = RPC_SND_METHOD_MIDI; 211 212 rc = audmgr_enable(&audio->audmgr, &cfg); 213 if (rc < 0) 214 return rc; 215 216 if (msm_adsp_enable(audio->audpre)) { 217 pr_err("audrec: msm_adsp_enable(audpre) failed\n"); 218 return -ENODEV; 219 } 220 if (msm_adsp_enable(audio->audrec)) { 221 pr_err("audrec: msm_adsp_enable(audrec) failed\n"); 222 return -ENODEV; 223 } 224 225 audio->enabled = 1; 226 audio_in_dsp_enable(audio, 1); 227 228 return 0; 229} 230 231/* must be called with audio->lock held */ 232static int audio_in_disable(struct audio_in *audio) 233{ 234 if (audio->enabled) { 235 audio->enabled = 0; 236 237 audio_in_dsp_enable(audio, 0); 238 239 wake_up(&audio->wait); 240 241 msm_adsp_disable(audio->audrec); 242 msm_adsp_disable(audio->audpre); 243 audmgr_disable(&audio->audmgr); 244 } 245 return 0; 246} 247 248/* ------------------- dsp --------------------- */ 249static void audpre_dsp_event(void *data, unsigned id, size_t len, 250 void (*getevent)(void *ptr, size_t len)) 251{ 252 uint16_t msg[2]; 253 getevent(msg, sizeof(msg)); 254 255 switch (id) { 256 case AUDPREPROC_MSG_CMD_CFG_DONE_MSG: 257 pr_info("audpre: type %d, status_flag %d\n", msg[0], msg[1]); 258 break; 259 case AUDPREPROC_MSG_ERROR_MSG_ID: 260 pr_info("audpre: err_index %d\n", msg[0]); 261 break; 262 default: 263 pr_err("audpre: unknown event %d\n", id); 264 } 265} 266 267struct audio_frame { 268 uint16_t count_low; 269 uint16_t count_high; 270 uint16_t bytes; 271 uint16_t unknown; 272 unsigned char samples[]; 273} __attribute__((packed)); 274 275static void audio_in_get_dsp_frames(struct audio_in *audio) 276{ 277 struct audio_frame *frame; 278 uint32_t index; 279 unsigned long flags; 280 281 index = audio->in_head; 282 283 284 frame = (void *) (((char *)audio->in[index].data) - sizeof(*frame)); 285 286 spin_lock_irqsave(&audio->dsp_lock, flags); 287 audio->in[index].size = frame->bytes; 288 289 audio->in_head = (audio->in_head + 1) & (FRAME_NUM - 1); 290 291 /* If overflow, move the tail index foward. */ 292 if (audio->in_head == audio->in_tail) 293 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); 294 else 295 audio->in_count++; 296 297 audio_dsp_read_buffer(audio, audio->dsp_cnt++); 298 spin_unlock_irqrestore(&audio->dsp_lock, flags); 299 300 wake_up(&audio->wait); 301} 302 303static void audrec_dsp_event(void *data, unsigned id, size_t len, 304 void (*getevent)(void *ptr, size_t len)) 305{ 306 struct audio_in *audio = data; 307 uint16_t msg[3]; 308 getevent(msg, sizeof(msg)); 309 310 switch (id) { 311 case AUDREC_MSG_CMD_CFG_DONE_MSG: 312 if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_UPDATE) { 313 if (msg[0] & AUDREC_MSG_CFG_DONE_TYPE_0_ENA) { 314 pr_info("audpre: CFG ENABLED\n"); 315 audio_dsp_set_agc(audio); 316 audio_dsp_set_ns(audio); 317 audio_dsp_set_tx_iir(audio); 318 audio_in_encoder_config(audio); 319 } else { 320 pr_info("audrec: CFG SLEEP\n"); 321 audio->running = 0; 322 } 323 } else { 324 pr_info("audrec: CMD_CFG_DONE %x\n", msg[0]); 325 } 326 break; 327 case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: { 328 pr_info("audrec: PARAM CFG DONE\n"); 329 audio->running = 1; 330 break; 331 } 332 case AUDREC_MSG_FATAL_ERR_MSG: 333 pr_err("audrec: ERROR %x\n", msg[0]); 334 break; 335 case AUDREC_MSG_PACKET_READY_MSG: 336/* REC_DBG("type %x, count %d", msg[0], (msg[1] | (msg[2] << 16))); */ 337 audio_in_get_dsp_frames(audio); 338 break; 339 default: 340 pr_err("audrec: unknown event %d\n", id); 341 } 342} 343 344struct msm_adsp_ops audpre_adsp_ops = { 345 .event = audpre_dsp_event, 346}; 347 348struct msm_adsp_ops audrec_adsp_ops = { 349 .event = audrec_dsp_event, 350}; 351 352 353#define audio_send_queue_pre(audio, cmd, len) \ 354 msm_adsp_write(audio->audpre, QDSP_uPAudPreProcCmdQueue, cmd, len) 355#define audio_send_queue_recbs(audio, cmd, len) \ 356 msm_adsp_write(audio->audrec, QDSP_uPAudRecBitStreamQueue, cmd, len) 357#define audio_send_queue_rec(audio, cmd, len) \ 358 msm_adsp_write(audio->audrec, \ 359 QDSP_uPAudRecCmdQueue, cmd, len) 360 361static int audio_dsp_set_agc(struct audio_in *audio) 362{ 363 audpreproc_cmd_cfg_agc_params cmd; 364 365 memset(&cmd, 0, sizeof(cmd)); 366 cmd.cmd_id = AUDPREPROC_CMD_CFG_AGC_PARAMS; 367 368 if (audio->agc_enable) { 369 /* cmd.tx_agc_param_mask = 0xFE00 from sample code */ 370 cmd.tx_agc_param_mask = 371 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_SLOPE) | 372 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_TH) | 373 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_SLOPE) | 374 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_EXP_TH) | 375 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_AIG_FLAG) | 376 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_COMP_STATIC_GAIN) | 377 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG); 378 cmd.tx_agc_enable_flag = 379 AUDPREPROC_CMD_TX_AGC_ENA_FLAG_ENA; 380 memcpy(&cmd.static_gain, &audio->agc.agc_params[0], 381 sizeof(uint16_t) * 6); 382 /* cmd.param_mask = 0xFFF0 from sample code */ 383 cmd.param_mask = 384 (1 << AUDPREPROC_CMD_PARAM_MASK_RMS_TAY) | 385 (1 << AUDPREPROC_CMD_PARAM_MASK_RELEASEK) | 386 (1 << AUDPREPROC_CMD_PARAM_MASK_DELAY) | 387 (1 << AUDPREPROC_CMD_PARAM_MASK_ATTACKK) | 388 (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_SLOW) | 389 (1 << AUDPREPROC_CMD_PARAM_MASK_LEAKRATE_FAST) | 390 (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_RELEASEK) | 391 (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MIN) | 392 (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_MAX) | 393 (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_UP) | 394 (1 << AUDPREPROC_CMD_PARAM_MASK_LEAK_DOWN) | 395 (1 << AUDPREPROC_CMD_PARAM_MASK_AIG_ATTACKK); 396 memcpy(&cmd.aig_attackk, &audio->agc.agc_params[6], 397 sizeof(uint16_t) * 14); 398 399 } else { 400 cmd.tx_agc_param_mask = 401 (1 << AUDPREPROC_CMD_TX_AGC_PARAM_MASK_TX_AGC_ENA_FLAG); 402 cmd.tx_agc_enable_flag = 403 AUDPREPROC_CMD_TX_AGC_ENA_FLAG_DIS; 404 } 405#if DEBUG 406 pr_info("cmd_id = 0x%04x\n", cmd.cmd_id); 407 pr_info("tx_agc_param_mask = 0x%04x\n", cmd.tx_agc_param_mask); 408 pr_info("tx_agc_enable_flag = 0x%04x\n", cmd.tx_agc_enable_flag); 409 pr_info("static_gain = 0x%04x\n", cmd.static_gain); 410 pr_info("adaptive_gain_flag = 0x%04x\n", cmd.adaptive_gain_flag); 411 pr_info("expander_th = 0x%04x\n", cmd.expander_th); 412 pr_info("expander_slope = 0x%04x\n", cmd.expander_slope); 413 pr_info("compressor_th = 0x%04x\n", cmd.compressor_th); 414 pr_info("compressor_slope = 0x%04x\n", cmd.compressor_slope); 415 pr_info("param_mask = 0x%04x\n", cmd.param_mask); 416 pr_info("aig_attackk = 0x%04x\n", cmd.aig_attackk); 417 pr_info("aig_leak_down = 0x%04x\n", cmd.aig_leak_down); 418 pr_info("aig_leak_up = 0x%04x\n", cmd.aig_leak_up); 419 pr_info("aig_max = 0x%04x\n", cmd.aig_max); 420 pr_info("aig_min = 0x%04x\n", cmd.aig_min); 421 pr_info("aig_releasek = 0x%04x\n", cmd.aig_releasek); 422 pr_info("aig_leakrate_fast = 0x%04x\n", cmd.aig_leakrate_fast); 423 pr_info("aig_leakrate_slow = 0x%04x\n", cmd.aig_leakrate_slow); 424 pr_info("attackk_msw = 0x%04x\n", cmd.attackk_msw); 425 pr_info("attackk_lsw = 0x%04x\n", cmd.attackk_lsw); 426 pr_info("delay = 0x%04x\n", cmd.delay); 427 pr_info("releasek_msw = 0x%04x\n", cmd.releasek_msw); 428 pr_info("releasek_lsw = 0x%04x\n", cmd.releasek_lsw); 429 pr_info("rms_tav = 0x%04x\n", cmd.rms_tav); 430#endif 431 return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); 432} 433 434static int audio_dsp_set_ns(struct audio_in *audio) 435{ 436 audpreproc_cmd_cfg_ns_params cmd; 437 438 memset(&cmd, 0, sizeof(cmd)); 439 cmd.cmd_id = AUDPREPROC_CMD_CFG_NS_PARAMS; 440 441 if (audio->ns_enable) { 442 /* cmd.ec_mode_new is fixed as 0x0064 when enable from sample code */ 443 cmd.ec_mode_new = 444 AUDPREPROC_CMD_EC_MODE_NEW_NS_ENA | 445 AUDPREPROC_CMD_EC_MODE_NEW_HB_ENA | 446 AUDPREPROC_CMD_EC_MODE_NEW_VA_ENA; 447 memcpy(&cmd.dens_gamma_n, &audio->ns.ns_params, 448 sizeof(audio->ns.ns_params)); 449 } else { 450 cmd.ec_mode_new = 451 AUDPREPROC_CMD_EC_MODE_NEW_NLMS_DIS | 452 AUDPREPROC_CMD_EC_MODE_NEW_DES_DIS | 453 AUDPREPROC_CMD_EC_MODE_NEW_NS_DIS | 454 AUDPREPROC_CMD_EC_MODE_NEW_CNI_DIS | 455 AUDPREPROC_CMD_EC_MODE_NEW_NLES_DIS | 456 AUDPREPROC_CMD_EC_MODE_NEW_HB_DIS | 457 AUDPREPROC_CMD_EC_MODE_NEW_VA_DIS | 458 AUDPREPROC_CMD_EC_MODE_NEW_PCD_DIS | 459 AUDPREPROC_CMD_EC_MODE_NEW_FEHI_DIS | 460 AUDPREPROC_CMD_EC_MODE_NEW_NEHI_DIS | 461 AUDPREPROC_CMD_EC_MODE_NEW_NLPP_DIS | 462 AUDPREPROC_CMD_EC_MODE_NEW_FNE_DIS | 463 AUDPREPROC_CMD_EC_MODE_NEW_PRENLMS_DIS; 464 } 465#if DEBUG 466 pr_info("cmd_id = 0x%04x\n", cmd.cmd_id); 467 pr_info("ec_mode_new = 0x%04x\n", cmd.ec_mode_new); 468 pr_info("dens_gamma_n = 0x%04x\n", cmd.dens_gamma_n); 469 pr_info("dens_nfe_block_size = 0x%04x\n", cmd.dens_nfe_block_size); 470 pr_info("dens_limit_ns = 0x%04x\n", cmd.dens_limit_ns); 471 pr_info("dens_limit_ns_d = 0x%04x\n", cmd.dens_limit_ns_d); 472 pr_info("wb_gamma_e = 0x%04x\n", cmd.wb_gamma_e); 473 pr_info("wb_gamma_n = 0x%04x\n", cmd.wb_gamma_n); 474#endif 475 return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); 476} 477 478static int audio_dsp_set_tx_iir(struct audio_in *audio) 479{ 480 struct audpre_cmd_iir_config_type cmd; 481 482 memset(&cmd, 0, sizeof(cmd)); 483 cmd.cmd_id = AUDPREPROC_CMD_CFG_IIR_TUNING_FILTER_PARAMS; 484 485 if (audio->iir_enable) { 486 cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_ENA; 487 cmd.num_bands = audio->iir.num_bands; 488 memcpy(&cmd.iir_params, &audio->iir.iir_params, 489 sizeof(audio->iir.iir_params)); 490 } else { 491 cmd.active_flag = AUDPREPROC_CMD_IIR_ACTIVE_FLAG_DIS; 492 } 493#if DEBUG 494 pr_info("cmd_id = 0x%04x\n", cmd.cmd_id); 495 pr_info("active_flag = 0x%04x\n", cmd.active_flag); 496#endif 497 return audio_send_queue_pre(audio, &cmd, sizeof(cmd)); 498} 499 500static int audio_in_dsp_enable(struct audio_in *audio, int enable) 501{ 502 audrec_cmd_cfg cmd; 503 504 memset(&cmd, 0, sizeof(cmd)); 505 cmd.cmd_id = AUDREC_CMD_CFG; 506 cmd.type_0 = enable ? AUDREC_CMD_TYPE_0_ENA : AUDREC_CMD_TYPE_0_DIS; 507 cmd.type_0 |= (AUDREC_CMD_TYPE_0_UPDATE | audio->type); 508 cmd.type_1 = 0; 509 510 return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); 511} 512 513static int audio_in_encoder_config(struct audio_in *audio) 514{ 515 audrec_cmd_arec0param_cfg cmd; 516 uint16_t *data = (void *) audio->data; 517 unsigned n; 518 519 memset(&cmd, 0, sizeof(cmd)); 520 cmd.cmd_id = AUDREC_CMD_AREC0PARAM_CFG; 521 cmd.ptr_to_extpkt_buffer_msw = audio->phys >> 16; 522 cmd.ptr_to_extpkt_buffer_lsw = audio->phys; 523 cmd.buf_len = FRAME_NUM; /* Both WAV and AAC use 8 frames */ 524 cmd.samp_rate_index = audio->samp_rate_index; 525 cmd.stereo_mode = audio->channel_mode; /* 0 for mono, 1 for stereo */ 526 527 cmd.rec_quality = 0x1C00; 528 529 /* prepare buffer pointers: 530 * Mono: 1024 samples + 4 halfword header 531 * Stereo: 2048 samples + 4 halfword header 532 * AAC 533 * Mono/Stere: 768 + 4 halfword header 534 */ 535 for (n = 0; n < FRAME_NUM; n++) { 536 audio->in[n].data = data + 4; 537 if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV) 538 data += (4 + (audio->channel_mode ? 2048 : 1024)); 539 else if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC) 540 data += (4 + 768); 541 } 542 543 return audio_send_queue_rec(audio, &cmd, sizeof(cmd)); 544} 545 546static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt) 547{ 548 audrec_cmd_packet_ext_ptr cmd; 549 550 memset(&cmd, 0, sizeof(cmd)); 551 cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR; 552 /* Both WAV and AAC use AUDREC_CMD_TYPE_0 */ 553 cmd.type = AUDREC_CMD_TYPE_0; 554 cmd.curr_rec_count_msw = read_cnt >> 16; 555 cmd.curr_rec_count_lsw = read_cnt; 556 557 return audio_send_queue_recbs(audio, &cmd, sizeof(cmd)); 558} 559 560/* ------------------- device --------------------- */ 561 562static void audio_enable_agc(struct audio_in *audio, int enable) 563{ 564 if (audio->agc_enable != enable) { 565 audio->agc_enable = enable; 566 if (audio->running) 567 audio_dsp_set_agc(audio); 568 } 569} 570 571static void audio_enable_ns(struct audio_in *audio, int enable) 572{ 573 if (audio->ns_enable != enable) { 574 audio->ns_enable = enable; 575 if (audio->running) 576 audio_dsp_set_ns(audio); 577 } 578} 579 580static void audio_enable_tx_iir(struct audio_in *audio, int enable) 581{ 582 if (audio->iir_enable != enable) { 583 audio->iir_enable = enable; 584 if (audio->running) 585 audio_dsp_set_tx_iir(audio); 586 } 587} 588 589static void audio_flush(struct audio_in *audio) 590{ 591 int i; 592 593 audio->dsp_cnt = 0; 594 audio->in_head = 0; 595 audio->in_tail = 0; 596 audio->in_count = 0; 597 for (i = 0; i < FRAME_NUM; i++) { 598 audio->in[i].size = 0; 599 audio->in[i].read = 0; 600 } 601} 602 603static long audio_in_ioctl(struct file *file, 604 unsigned int cmd, unsigned long arg) 605{ 606 struct audio_in *audio = file->private_data; 607 int rc; 608 609 if (cmd == AUDIO_GET_STATS) { 610 struct msm_audio_stats stats; 611 stats.byte_count = atomic_read(&audio->in_bytes); 612 if (copy_to_user((void *) arg, &stats, sizeof(stats))) 613 return -EFAULT; 614 return 0; 615 } 616 617 mutex_lock(&audio->lock); 618 switch (cmd) { 619 case AUDIO_START: 620 rc = audio_in_enable(audio); 621 break; 622 case AUDIO_STOP: 623 rc = audio_in_disable(audio); 624 audio->stopped = 1; 625 break; 626 case AUDIO_FLUSH: 627 if (audio->stopped) { 628 /* Make sure we're stopped and we wake any threads 629 * that might be blocked holding the read_lock. 630 * While audio->stopped read threads will always 631 * exit immediately. 632 */ 633 wake_up(&audio->wait); 634 mutex_lock(&audio->read_lock); 635 audio_flush(audio); 636 mutex_unlock(&audio->read_lock); 637 } 638 case AUDIO_SET_CONFIG: { 639 struct msm_audio_config cfg; 640 if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) { 641 rc = -EFAULT; 642 break; 643 } 644 if (cfg.channel_count == 1) { 645 cfg.channel_count = AUDREC_CMD_STEREO_MODE_MONO; 646 } else if (cfg.channel_count == 2) { 647 cfg.channel_count = AUDREC_CMD_STEREO_MODE_STEREO; 648 } else { 649 rc = -EINVAL; 650 break; 651 } 652 653 if (cfg.type == 0) { 654 cfg.type = AUDREC_CMD_TYPE_0_INDEX_WAV; 655 } else if (cfg.type == 1) { 656 cfg.type = AUDREC_CMD_TYPE_0_INDEX_AAC; 657 } else { 658 rc = -EINVAL; 659 break; 660 } 661 audio->samp_rate = convert_samp_rate(cfg.sample_rate); 662 audio->samp_rate_index = 663 convert_dsp_samp_index(cfg.sample_rate); 664 audio->channel_mode = cfg.channel_count; 665 audio->buffer_size = 666 audio->channel_mode ? STEREO_DATA_SIZE 667 : MONO_DATA_SIZE; 668 audio->type = cfg.type; 669 rc = 0; 670 break; 671 } 672 case AUDIO_GET_CONFIG: { 673 struct msm_audio_config cfg; 674 cfg.buffer_size = audio->buffer_size; 675 cfg.buffer_count = FRAME_NUM; 676 cfg.sample_rate = convert_samp_index(audio->samp_rate); 677 if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO) 678 cfg.channel_count = 1; 679 else 680 cfg.channel_count = 2; 681 if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV) 682 cfg.type = 0; 683 else 684 cfg.type = 1; 685 cfg.unused[0] = 0; 686 cfg.unused[1] = 0; 687 cfg.unused[2] = 0; 688 if (copy_to_user((void *) arg, &cfg, sizeof(cfg))) 689 rc = -EFAULT; 690 else 691 rc = 0; 692 break; 693 } 694 default: 695 rc = -EINVAL; 696 } 697 mutex_unlock(&audio->lock); 698 return rc; 699} 700 701static ssize_t audio_in_read(struct file *file, 702 char __user *buf, 703 size_t count, loff_t *pos) 704{ 705 struct audio_in *audio = file->private_data; 706 unsigned long flags; 707 const char __user *start = buf; 708 void *data; 709 uint32_t index; 710 uint32_t size; 711 int rc = 0; 712 713 mutex_lock(&audio->read_lock); 714 while (count > 0) { 715 rc = wait_event_interruptible( 716 audio->wait, (audio->in_count > 0) || audio->stopped); 717 if (rc < 0) 718 break; 719 720 if (audio->stopped) { 721 rc = -EBUSY; 722 break; 723 } 724 725 index = audio->in_tail; 726 data = (uint8_t *) audio->in[index].data; 727 size = audio->in[index].size; 728 if (count >= size) { 729 if (copy_to_user(buf, data, size)) { 730 rc = -EFAULT; 731 break; 732 } 733 spin_lock_irqsave(&audio->dsp_lock, flags); 734 if (index != audio->in_tail) { 735 /* overrun -- data is invalid and we need to retry */ 736 spin_unlock_irqrestore(&audio->dsp_lock, flags); 737 continue; 738 } 739 audio->in[index].size = 0; 740 audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1); 741 audio->in_count--; 742 spin_unlock_irqrestore(&audio->dsp_lock, flags); 743 count -= size; 744 buf += size; 745 if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC) 746 break; 747 } else { 748 pr_err("audio_in: short read\n"); 749 break; 750 } 751 if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC) 752 break; /* AAC only read one frame */ 753 } 754 mutex_unlock(&audio->read_lock); 755 756 if (buf > start) 757 return buf - start; 758 759 return rc; 760} 761 762static ssize_t audio_in_write(struct file *file, 763 const char __user *buf, 764 size_t count, loff_t *pos) 765{ 766 return -EINVAL; 767} 768 769static int audio_in_release(struct inode *inode, struct file *file) 770{ 771 struct audio_in *audio = file->private_data; 772 773 mutex_lock(&audio->lock); 774 audio_in_disable(audio); 775 audio_flush(audio); 776 msm_adsp_put(audio->audrec); 777 msm_adsp_put(audio->audpre); 778 audio->audrec = NULL; 779 audio->audpre = NULL; 780 audio->opened = 0; 781 mutex_unlock(&audio->lock); 782 return 0; 783} 784 785static struct audio_in the_audio_in; 786 787static int audio_in_open(struct inode *inode, struct file *file) 788{ 789 struct audio_in *audio = &the_audio_in; 790 int rc; 791 792 mutex_lock(&audio->lock); 793 if (audio->opened) { 794 rc = -EBUSY; 795 goto done; 796 } 797 798 /* Settings will be re-config at AUDIO_SET_CONFIG, 799 * but at least we need to have initial config 800 */ 801 audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025; 802 audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025; 803 audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO; 804 audio->buffer_size = MONO_DATA_SIZE; 805 audio->type = AUDREC_CMD_TYPE_0_INDEX_WAV; 806 807 rc = audmgr_open(&audio->audmgr); 808 if (rc) 809 goto done; 810 rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre, 811 &audpre_adsp_ops, audio); 812 if (rc) 813 goto done; 814 rc = msm_adsp_get("AUDRECTASK", &audio->audrec, 815 &audrec_adsp_ops, audio); 816 if (rc) 817 goto done; 818 819 audio->dsp_cnt = 0; 820 audio->stopped = 0; 821 822 audio_flush(audio); 823 824 file->private_data = audio; 825 audio->opened = 1; 826 rc = 0; 827done: 828 mutex_unlock(&audio->lock); 829 return rc; 830} 831 832static long audpre_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 833{ 834 struct audio_in *audio = file->private_data; 835 int rc = 0, enable; 836 uint16_t enable_mask; 837#if DEBUG 838 int i; 839#endif 840 841 mutex_lock(&audio->lock); 842 switch (cmd) { 843 case AUDIO_ENABLE_AUDPRE: { 844 if (copy_from_user(&enable_mask, (void *) arg, 845 sizeof(enable_mask))) 846 goto out_fault; 847 848 enable = (enable_mask & AGC_ENABLE) ? 1 : 0; 849 audio_enable_agc(audio, enable); 850 enable = (enable_mask & NS_ENABLE) ? 1 : 0; 851 audio_enable_ns(audio, enable); 852 enable = (enable_mask & IIR_ENABLE) ? 1 : 0; 853 audio_enable_tx_iir(audio, enable); 854 break; 855 } 856 case AUDIO_SET_AGC: { 857 if (copy_from_user(&audio->agc, (void *) arg, 858 sizeof(audio->agc))) 859 goto out_fault; 860#if DEBUG 861 pr_info("set agc\n"); 862 for (i = 0; i < AGC_PARAM_SIZE; i++) \ 863 pr_info("agc_params[%d] = 0x%04x\n", i, 864 audio->agc.agc_params[i]); 865#endif 866 break; 867 } 868 case AUDIO_SET_NS: { 869 if (copy_from_user(&audio->ns, (void *) arg, 870 sizeof(audio->ns))) 871 goto out_fault; 872#if DEBUG 873 pr_info("set ns\n"); 874 for (i = 0; i < NS_PARAM_SIZE; i++) \ 875 pr_info("ns_params[%d] = 0x%04x\n", 876 i, audio->ns.ns_params[i]); 877#endif 878 break; 879 } 880 case AUDIO_SET_TX_IIR: { 881 if (copy_from_user(&audio->iir, (void *) arg, 882 sizeof(audio->iir))) 883 goto out_fault; 884#if DEBUG 885 pr_info("set iir\n"); 886 pr_info("iir.num_bands = 0x%04x\n", audio->iir.num_bands); 887 for (i = 0; i < IIR_PARAM_SIZE; i++) \ 888 pr_info("iir_params[%d] = 0x%04x\n", 889 i, audio->iir.iir_params[i]); 890#endif 891 break; 892 } 893 default: 894 rc = -EINVAL; 895 } 896 897 goto out; 898 899out_fault: 900 rc = -EFAULT; 901out: 902 mutex_unlock(&audio->lock); 903 return rc; 904} 905 906static int audpre_open(struct inode *inode, struct file *file) 907{ 908 struct audio_in *audio = &the_audio_in; 909 file->private_data = audio; 910 return 0; 911} 912 913static struct file_operations audio_fops = { 914 .owner = THIS_MODULE, 915 .open = audio_in_open, 916 .release = audio_in_release, 917 .read = audio_in_read, 918 .write = audio_in_write, 919 .unlocked_ioctl = audio_in_ioctl, 920}; 921 922static struct file_operations audpre_fops = { 923 .owner = THIS_MODULE, 924 .open = audpre_open, 925 .unlocked_ioctl = audpre_ioctl, 926}; 927 928struct miscdevice audio_in_misc = { 929 .minor = MISC_DYNAMIC_MINOR, 930 .name = "msm_pcm_in", 931 .fops = &audio_fops, 932}; 933 934struct miscdevice audpre_misc = { 935 .minor = MISC_DYNAMIC_MINOR, 936 .name = "msm_audpre", 937 .fops = &audpre_fops, 938}; 939 940static int __init audio_in_init(void) 941{ 942 int rc; 943 the_audio_in.data = dma_alloc_coherent(NULL, DMASZ, 944 &the_audio_in.phys, GFP_KERNEL); 945 if (!the_audio_in.data) { 946 printk(KERN_ERR "%s: Unable to allocate DMA buffer\n", 947 __func__); 948 return -ENOMEM; 949 } 950 951 mutex_init(&the_audio_in.lock); 952 mutex_init(&the_audio_in.read_lock); 953 spin_lock_init(&the_audio_in.dsp_lock); 954 init_waitqueue_head(&the_audio_in.wait); 955 rc = misc_register(&audio_in_misc); 956 if (!rc) { 957 rc = misc_register(&audpre_misc); 958 if (rc < 0) 959 misc_deregister(&audio_in_misc); 960 } 961 return rc; 962} 963 964device_initcall(audio_in_init); 965