1/* linux/arch/arm/mach-msm/qdsp5/audio_amrnb.c 2 * 3 * amrnb audio decoder device 4 * 5 * Copyright (c) 2008 QUALCOMM USA, INC. 6 * 7 * Based on the mp3 native driver in arch/arm/mach-msm/qdsp5/audio_mp3.c 8 * 9 * Copyright (C) 2008 Google, Inc. 10 * Copyright (C) 2008 HTC Corporation 11 * 12 * All source code in this file is licensed under the following license except 13 * where indicated. 14 * 15 * This program is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU General Public License version 2 as published 17 * by the Free Software Foundation. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 22 * 23 * See the GNU General Public License for more details. 24 * You should have received a copy of the GNU General Public License 25 * along with this program; if not, you can find it at http://www.fsf.org 26 */ 27 28#include <linux/module.h> 29#include <linux/fs.h> 30#include <linux/miscdevice.h> 31#include <linux/uaccess.h> 32#include <linux/kthread.h> 33#include <linux/wait.h> 34#include <linux/dma-mapping.h> 35#include <linux/gfp.h> 36 37#include <linux/delay.h> 38 39#include <asm/atomic.h> 40#include <asm/ioctls.h> 41#include <mach/msm_adsp.h> 42#include <linux/msm_audio.h> 43#include "audmgr.h" 44 45#include <mach/qdsp5/qdsp5audppcmdi.h> 46#include <mach/qdsp5/qdsp5audppmsg.h> 47#include <mach/qdsp5/qdsp5audplaycmdi.h> 48#include <mach/qdsp5/qdsp5audplaymsg.h> 49 50/* for queue ids - should be relative to module number*/ 51#include "adsp.h" 52 53#define DEBUG 54#ifdef DEBUG 55#define dprintk(format, arg...) \ 56printk(KERN_DEBUG format, ## arg) 57#else 58#define dprintk(format, arg...) do {} while (0) 59#endif 60 61#define BUFSZ 1024 /* Hold minimum 700ms voice data */ 62#define DMASZ (BUFSZ * 2) 63 64#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF 65#define AUDDEC_DEC_AMRNB 10 66 67#define PCM_BUFSZ_MIN 1600 /* 100ms worth of data */ 68#define AMRNB_DECODED_FRSZ 320 /* AMR-NB 20ms 8KHz mono PCM size */ 69#define PCM_BUF_MAX_COUNT 5 /* DSP only accepts 5 buffers at most 70 but support 2 buffers currently */ 71#define ROUTING_MODE_FTRT 1 72#define ROUTING_MODE_RT 2 73/* Decoder status received from AUDPPTASK */ 74#define AUDPP_DEC_STATUS_SLEEP 0 75#define AUDPP_DEC_STATUS_INIT 1 76#define AUDPP_DEC_STATUS_CFG 2 77#define AUDPP_DEC_STATUS_PLAY 3 78 79struct buffer { 80 void *data; 81 unsigned size; 82 unsigned used; /* Input usage actual DSP produced PCM size */ 83 unsigned addr; 84}; 85 86struct audio { 87 struct buffer out[2]; 88 89 spinlock_t dsp_lock; 90 91 uint8_t out_head; 92 uint8_t out_tail; 93 uint8_t out_needed; /* number of buffers the dsp is waiting for */ 94 95 atomic_t out_bytes; 96 97 struct mutex lock; 98 struct mutex write_lock; 99 wait_queue_head_t write_wait; 100 101 /* Host PCM section */ 102 struct buffer in[PCM_BUF_MAX_COUNT]; 103 struct mutex read_lock; 104 wait_queue_head_t read_wait; /* Wait queue for read */ 105 char *read_data; /* pointer to reader buffer */ 106 dma_addr_t read_phys; /* physical address of reader buffer */ 107 uint8_t read_next; /* index to input buffers to be read next */ 108 uint8_t fill_next; /* index to buffer that DSP should be filling */ 109 uint8_t pcm_buf_count; /* number of pcm buffer allocated */ 110 /* ---- End of Host PCM section */ 111 112 struct msm_adsp_module *audplay; 113 114 struct audmgr audmgr; 115 116 /* data allocated for various buffers */ 117 char *data; 118 dma_addr_t phys; 119 120 uint8_t opened:1; 121 uint8_t enabled:1; 122 uint8_t running:1; 123 uint8_t stopped:1; /* set when stopped, cleared on flush */ 124 uint8_t pcm_feedback:1; 125 uint8_t buf_refresh:1; 126 127 unsigned volume; 128 129 uint16_t dec_id; 130 uint32_t read_ptr_offset; 131}; 132 133struct audpp_cmd_cfg_adec_params_amrnb { 134 audpp_cmd_cfg_adec_params_common common; 135 unsigned short stereo_cfg; 136} __attribute__((packed)) ; 137 138static int auddec_dsp_config(struct audio *audio, int enable); 139static void audpp_cmd_cfg_adec_params(struct audio *audio); 140static void audpp_cmd_cfg_routing_mode(struct audio *audio); 141static void audamrnb_send_data(struct audio *audio, unsigned needed); 142static void audamrnb_config_hostpcm(struct audio *audio); 143static void audamrnb_buffer_refresh(struct audio *audio); 144static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg); 145 146/* must be called with audio->lock held */ 147static int audamrnb_enable(struct audio *audio) 148{ 149 struct audmgr_config cfg; 150 int rc; 151 152 dprintk("audamrnb_enable()\n"); 153 154 if (audio->enabled) 155 return 0; 156 157 audio->out_tail = 0; 158 audio->out_needed = 0; 159 160 cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE; 161 cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000; 162 cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK; 163 cfg.codec = RPC_AUD_DEF_CODEC_AMR_NB; 164 cfg.snd_method = RPC_SND_METHOD_MIDI; 165 166 rc = audmgr_enable(&audio->audmgr, &cfg); 167 if (rc < 0) 168 return rc; 169 170 if (msm_adsp_enable(audio->audplay)) { 171 pr_err("audio: msm_adsp_enable(audplay) failed\n"); 172 audmgr_disable(&audio->audmgr); 173 return -ENODEV; 174 } 175 176 if (audpp_enable(audio->dec_id, audamrnb_dsp_event, audio)) { 177 pr_err("audio: audpp_enable() failed\n"); 178 msm_adsp_disable(audio->audplay); 179 audmgr_disable(&audio->audmgr); 180 return -ENODEV; 181 } 182 audio->enabled = 1; 183 return 0; 184} 185 186/* must be called with audio->lock held */ 187static int audamrnb_disable(struct audio *audio) 188{ 189 dprintk("audamrnb_disable()\n"); 190 if (audio->enabled) { 191 audio->enabled = 0; 192 auddec_dsp_config(audio, 0); 193 wake_up(&audio->write_wait); 194 wake_up(&audio->read_wait); 195 msm_adsp_disable(audio->audplay); 196 audpp_disable(audio->dec_id, audio); 197 audmgr_disable(&audio->audmgr); 198 audio->out_needed = 0; 199 } 200 return 0; 201} 202 203/* ------------------- dsp --------------------- */ 204static void audamrnb_update_pcm_buf_entry(struct audio *audio, 205 uint32_t *payload) 206{ 207 uint8_t index; 208 unsigned long flags; 209 210 spin_lock_irqsave(&audio->dsp_lock, flags); 211 for (index = 0; index < payload[1]; index++) { 212 if (audio->in[audio->fill_next].addr == 213 payload[2 + index * 2]) { 214 dprintk("audamrnb_update_pcm_buf_entry: in[%d] ready\n", 215 audio->fill_next); 216 audio->in[audio->fill_next].used = 217 payload[3 + index * 2]; 218 if ((++audio->fill_next) == audio->pcm_buf_count) 219 audio->fill_next = 0; 220 221 } else { 222 pr_err 223 ("audamrnb_update_pcm_buf_entry: expected=%x ret=%x\n" 224 , audio->in[audio->fill_next].addr, 225 payload[1 + index * 2]); 226 break; 227 } 228 } 229 if (audio->in[audio->fill_next].used == 0) { 230 audamrnb_buffer_refresh(audio); 231 } else { 232 dprintk("audamrnb_update_pcm_buf_entry: read cannot keep up\n"); 233 audio->buf_refresh = 1; 234 } 235 236 spin_unlock_irqrestore(&audio->dsp_lock, flags); 237 wake_up(&audio->read_wait); 238} 239 240static void audplay_dsp_event(void *data, unsigned id, size_t len, 241 void (*getevent) (void *ptr, size_t len)) 242{ 243 struct audio *audio = data; 244 uint32_t msg[28]; 245 getevent(msg, sizeof(msg)); 246 247 dprintk("audplay_dsp_event: msg_id=%x\n", id); 248 249 switch (id) { 250 case AUDPLAY_MSG_DEC_NEEDS_DATA: 251 audamrnb_send_data(audio, 1); 252 break; 253 254 case AUDPLAY_MSG_BUFFER_UPDATE: 255 audamrnb_update_pcm_buf_entry(audio, msg); 256 break; 257 258 default: 259 pr_err("unexpected message from decoder \n"); 260 } 261} 262 263static void audamrnb_dsp_event(void *private, unsigned id, uint16_t *msg) 264{ 265 struct audio *audio = private; 266 267 switch (id) { 268 case AUDPP_MSG_STATUS_MSG:{ 269 unsigned status = msg[1]; 270 271 switch (status) { 272 case AUDPP_DEC_STATUS_SLEEP: 273 dprintk("decoder status: sleep \n"); 274 break; 275 276 case AUDPP_DEC_STATUS_INIT: 277 dprintk("decoder status: init \n"); 278 audpp_cmd_cfg_routing_mode(audio); 279 break; 280 281 case AUDPP_DEC_STATUS_CFG: 282 dprintk("decoder status: cfg \n"); 283 break; 284 case AUDPP_DEC_STATUS_PLAY: 285 dprintk("decoder status: play \n"); 286 if (audio->pcm_feedback) { 287 audamrnb_config_hostpcm(audio); 288 audamrnb_buffer_refresh(audio); 289 } 290 break; 291 default: 292 pr_err("unknown decoder status \n"); 293 break; 294 } 295 break; 296 } 297 case AUDPP_MSG_CFG_MSG: 298 if (msg[0] == AUDPP_MSG_ENA_ENA) { 299 dprintk("audamrnb_dsp_event: CFG_MSG ENABLE\n"); 300 auddec_dsp_config(audio, 1); 301 audio->out_needed = 0; 302 audio->running = 1; 303 audpp_set_volume_and_pan(audio->dec_id, audio->volume, 304 0); 305 audpp_avsync(audio->dec_id, 22050); 306 } else if (msg[0] == AUDPP_MSG_ENA_DIS) { 307 dprintk("audamrnb_dsp_event: CFG_MSG DISABLE\n"); 308 audpp_avsync(audio->dec_id, 0); 309 audio->running = 0; 310 } else { 311 pr_err("audamrnb_dsp_event: CFG_MSG %d?\n", msg[0]); 312 } 313 break; 314 case AUDPP_MSG_ROUTING_ACK: 315 dprintk("audamrnb_dsp_event: ROUTING_ACK mode=%d\n", msg[1]); 316 audpp_cmd_cfg_adec_params(audio); 317 break; 318 319 default: 320 pr_err("audamrnb_dsp_event: UNKNOWN (%d)\n", id); 321 } 322 323} 324 325struct msm_adsp_ops audplay_adsp_ops_amrnb = { 326 .event = audplay_dsp_event, 327}; 328 329#define audplay_send_queue0(audio, cmd, len) \ 330 msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \ 331 cmd, len) 332 333static int auddec_dsp_config(struct audio *audio, int enable) 334{ 335 audpp_cmd_cfg_dec_type cmd; 336 337 memset(&cmd, 0, sizeof(cmd)); 338 cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE; 339 if (enable) 340 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | 341 AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AMRNB; 342 else 343 cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V; 344 345 return audpp_send_queue1(&cmd, sizeof(cmd)); 346} 347 348static void audpp_cmd_cfg_adec_params(struct audio *audio) 349{ 350 struct audpp_cmd_cfg_adec_params_amrnb cmd; 351 352 memset(&cmd, 0, sizeof(cmd)); 353 cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS; 354 cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_V13K_LEN; 355 cmd.common.dec_id = audio->dec_id; 356 cmd.common.input_sampling_frequency = 8000; 357 cmd.stereo_cfg = AUDPP_CMD_PCM_INTF_MONO_V; 358 359 audpp_send_queue2(&cmd, sizeof(cmd)); 360} 361 362static void audpp_cmd_cfg_routing_mode(struct audio *audio) 363{ 364 struct audpp_cmd_routing_mode cmd; 365 dprintk("audpp_cmd_cfg_routing_mode()\n"); 366 memset(&cmd, 0, sizeof(cmd)); 367 cmd.cmd_id = AUDPP_CMD_ROUTING_MODE; 368 cmd.object_number = audio->dec_id; 369 if (audio->pcm_feedback) 370 cmd.routing_mode = ROUTING_MODE_FTRT; 371 else 372 cmd.routing_mode = ROUTING_MODE_RT; 373 374 audpp_send_queue1(&cmd, sizeof(cmd)); 375} 376 377static int audplay_dsp_send_data_avail(struct audio *audio, 378 unsigned idx, unsigned len) 379{ 380 audplay_cmd_bitstream_data_avail cmd; 381 382 cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL; 383 cmd.decoder_id = audio->dec_id; 384 cmd.buf_ptr = audio->out[idx].addr; 385 cmd.buf_size = len / 2; 386 cmd.partition_number = 0; 387 return audplay_send_queue0(audio, &cmd, sizeof(cmd)); 388} 389 390static void audamrnb_buffer_refresh(struct audio *audio) 391{ 392 struct audplay_cmd_buffer_refresh refresh_cmd; 393 394 refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH; 395 refresh_cmd.num_buffers = 1; 396 refresh_cmd.buf0_address = audio->in[audio->fill_next].addr; 397 refresh_cmd.buf0_length = audio->in[audio->fill_next].size - 398 (audio->in[audio->fill_next].size % AMRNB_DECODED_FRSZ); 399 refresh_cmd.buf_read_count = 0; 400 dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n", 401 refresh_cmd.buf0_address, refresh_cmd.buf0_length); 402 (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd)); 403} 404 405static void audamrnb_config_hostpcm(struct audio *audio) 406{ 407 struct audplay_cmd_hpcm_buf_cfg cfg_cmd; 408 409 dprintk("audamrnb_config_hostpcm()\n"); 410 cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG; 411 cfg_cmd.max_buffers = audio->pcm_buf_count; 412 cfg_cmd.byte_swap = 0; 413 cfg_cmd.hostpcm_config = (0x8000) | (0x4000); 414 cfg_cmd.feedback_frequency = 1; 415 cfg_cmd.partition_number = 0; 416 (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd)); 417 418} 419 420static void audamrnb_send_data(struct audio *audio, unsigned needed) 421{ 422 struct buffer *frame; 423 unsigned long flags; 424 425 spin_lock_irqsave(&audio->dsp_lock, flags); 426 if (!audio->running) 427 goto done; 428 429 if (needed) { 430 /* We were called from the callback because the DSP 431 * requested more data. Note that the DSP does want 432 * more data, and if a buffer was in-flight, mark it 433 * as available (since the DSP must now be done with 434 * it). 435 */ 436 audio->out_needed = 1; 437 frame = audio->out + audio->out_tail; 438 if (frame->used == 0xffffffff) { 439 frame->used = 0; 440 audio->out_tail ^= 1; 441 wake_up(&audio->write_wait); 442 } 443 } 444 445 if (audio->out_needed) { 446 /* If the DSP currently wants data and we have a 447 * buffer available, we will send it and reset 448 * the needed flag. We'll mark the buffer as in-flight 449 * so that it won't be recycled until the next buffer 450 * is requested 451 */ 452 453 frame = audio->out + audio->out_tail; 454 if (frame->used) { 455 BUG_ON(frame->used == 0xffffffff); 456/* printk("frame %d busy\n", audio->out_tail); */ 457 audplay_dsp_send_data_avail(audio, audio->out_tail, 458 frame->used); 459 frame->used = 0xffffffff; 460 audio->out_needed = 0; 461 } 462 } 463 done: 464 spin_unlock_irqrestore(&audio->dsp_lock, flags); 465} 466 467/* ------------------- device --------------------- */ 468 469static void audamrnb_flush(struct audio *audio) 470{ 471 audio->out[0].used = 0; 472 audio->out[1].used = 0; 473 audio->out_head = 0; 474 audio->out_tail = 0; 475 audio->stopped = 0; 476 atomic_set(&audio->out_bytes, 0); 477} 478 479static void audamrnb_flush_pcm_buf(struct audio *audio) 480{ 481 uint8_t index; 482 483 for (index = 0; index < PCM_BUF_MAX_COUNT; index++) 484 audio->in[index].used = 0; 485 486 audio->read_next = 0; 487 audio->fill_next = 0; 488} 489 490static long audamrnb_ioctl(struct file *file, unsigned int cmd, 491 unsigned long arg) 492{ 493 struct audio *audio = file->private_data; 494 int rc = 0; 495 496 dprintk("audamrnb_ioctl() cmd = %d\n", cmd); 497 498 if (cmd == AUDIO_GET_STATS) { 499 struct msm_audio_stats stats; 500 stats.byte_count = audpp_avsync_byte_count(audio->dec_id); 501 stats.sample_count = audpp_avsync_sample_count(audio->dec_id); 502 if (copy_to_user((void *)arg, &stats, sizeof(stats))) 503 return -EFAULT; 504 return 0; 505 } 506 if (cmd == AUDIO_SET_VOLUME) { 507 unsigned long flags; 508 spin_lock_irqsave(&audio->dsp_lock, flags); 509 audio->volume = arg; 510 if (audio->running) 511 audpp_set_volume_and_pan(audio->dec_id, arg, 0); 512 spin_unlock_irqrestore(&audio->dsp_lock, flags); 513 return 0; 514 } 515 mutex_lock(&audio->lock); 516 switch (cmd) { 517 case AUDIO_START: 518 rc = audamrnb_enable(audio); 519 break; 520 case AUDIO_STOP: 521 rc = audamrnb_disable(audio); 522 audio->stopped = 1; 523 break; 524 case AUDIO_FLUSH: 525 if (audio->stopped) { 526 /* Make sure we're stopped and we wake any threads 527 * that might be blocked holding the write_lock. 528 * While audio->stopped write threads will always 529 * exit immediately. 530 */ 531 wake_up(&audio->write_wait); 532 mutex_lock(&audio->write_lock); 533 audamrnb_flush(audio); 534 mutex_unlock(&audio->write_lock); 535 wake_up(&audio->read_wait); 536 mutex_lock(&audio->read_lock); 537 audamrnb_flush_pcm_buf(audio); 538 mutex_unlock(&audio->read_lock); 539 break; 540 } 541 542 case AUDIO_SET_CONFIG:{ 543 dprintk("AUDIO_SET_CONFIG not applicable \n"); 544 break; 545 } 546 case AUDIO_GET_CONFIG:{ 547 struct msm_audio_config config; 548 config.buffer_size = BUFSZ; 549 config.buffer_count = 2; 550 config.sample_rate = 8000; 551 config.channel_count = 1; 552 config.unused[0] = 0; 553 config.unused[1] = 0; 554 config.unused[2] = 0; 555 config.unused[3] = 0; 556 if (copy_to_user((void *)arg, &config, 557 sizeof(config))) 558 rc = -EFAULT; 559 else 560 rc = 0; 561 562 break; 563 } 564 case AUDIO_GET_PCM_CONFIG:{ 565 struct msm_audio_pcm_config config; 566 config.pcm_feedback = 0; 567 config.buffer_count = PCM_BUF_MAX_COUNT; 568 config.buffer_size = PCM_BUFSZ_MIN; 569 if (copy_to_user((void *)arg, &config, 570 sizeof(config))) 571 rc = -EFAULT; 572 else 573 rc = 0; 574 break; 575 } 576 case AUDIO_SET_PCM_CONFIG:{ 577 struct msm_audio_pcm_config config; 578 if (copy_from_user 579 (&config, (void *)arg, sizeof(config))) { 580 rc = -EFAULT; 581 break; 582 } 583 if ((config.buffer_count > PCM_BUF_MAX_COUNT) || 584 (config.buffer_count == 1)) 585 config.buffer_count = PCM_BUF_MAX_COUNT; 586 587 if (config.buffer_size < PCM_BUFSZ_MIN) 588 config.buffer_size = PCM_BUFSZ_MIN; 589 590 /* Check if pcm feedback is required */ 591 if ((config.pcm_feedback) && (!audio->read_data)) { 592 dprintk("audamrnb_ioctl: allocate PCM buf %d\n", 593 config.buffer_count * 594 config.buffer_size); 595 audio->read_data = 596 dma_alloc_coherent(NULL, 597 config.buffer_size * 598 config.buffer_count, 599 &audio->read_phys, 600 GFP_KERNEL); 601 if (!audio->read_data) { 602 pr_err("audamrnb_ioctl: no mem for pcm buf\n"); 603 rc = -1; 604 } else { 605 uint8_t index; 606 uint32_t offset = 0; 607 audio->pcm_feedback = 1; 608 audio->buf_refresh = 0; 609 audio->pcm_buf_count = 610 config.buffer_count; 611 audio->read_next = 0; 612 audio->fill_next = 0; 613 614 for (index = 0; 615 index < config.buffer_count; index++) { 616 audio->in[index].data = 617 audio->read_data + offset; 618 audio->in[index].addr = 619 audio->read_phys + offset; 620 audio->in[index].size = 621 config.buffer_size; 622 audio->in[index].used = 0; 623 offset += config.buffer_size; 624 } 625 rc = 0; 626 } 627 } else { 628 rc = 0; 629 } 630 break; 631 } 632 default: 633 rc = -EINVAL; 634 } 635 mutex_unlock(&audio->lock); 636 return rc; 637} 638 639static ssize_t audamrnb_read(struct file *file, char __user *buf, size_t count, 640 loff_t *pos) 641{ 642 struct audio *audio = file->private_data; 643 const char __user *start = buf; 644 int rc = 0; 645 646 if (!audio->pcm_feedback) 647 return 0; /* PCM feedback is not enabled. Nothing to read */ 648 649 mutex_lock(&audio->read_lock); 650 dprintk("audamrnb_read() %d \n", count); 651 while (count > 0) { 652 rc = wait_event_interruptible(audio->read_wait, 653 (audio->in[audio->read_next]. 654 used > 0) || (audio->stopped)); 655 656 if (rc < 0) 657 break; 658 659 if (audio->stopped) { 660 rc = -EBUSY; 661 break; 662 } 663 664 if (count < audio->in[audio->read_next].used) { 665 /* Read must happen in frame boundary. Since driver does 666 * not know frame size, read count must be greater or 667 * equal to size of PCM samples 668 */ 669 dprintk("audamrnb_read:read stop - partial frame\n"); 670 break; 671 } else { 672 dprintk("audamrnb_read: read from in[%d]\n", 673 audio->read_next); 674 if (copy_to_user 675 (buf, audio->in[audio->read_next].data, 676 audio->in[audio->read_next].used)) { 677 pr_err("audamrnb_read: invalid addr %x \n", 678 (unsigned int)buf); 679 rc = -EFAULT; 680 break; 681 } 682 count -= audio->in[audio->read_next].used; 683 buf += audio->in[audio->read_next].used; 684 audio->in[audio->read_next].used = 0; 685 if ((++audio->read_next) == audio->pcm_buf_count) 686 audio->read_next = 0; 687 } 688 } 689 690 if (audio->buf_refresh) { 691 audio->buf_refresh = 0; 692 dprintk("audamrnb_read: kick start pcm feedback again\n"); 693 audamrnb_buffer_refresh(audio); 694 } 695 696 mutex_unlock(&audio->read_lock); 697 698 if (buf > start) 699 rc = buf - start; 700 701 dprintk("audamrnb_read: read %d bytes\n", rc); 702 return rc; 703} 704 705static ssize_t audamrnb_write(struct file *file, const char __user *buf, 706 size_t count, loff_t *pos) 707{ 708 struct audio *audio = file->private_data; 709 const char __user *start = buf; 710 struct buffer *frame; 711 size_t xfer; 712 int rc = 0; 713 714 if (count & 1) 715 return -EINVAL; 716 dprintk("audamrnb_write() \n"); 717 mutex_lock(&audio->write_lock); 718 while (count > 0) { 719 frame = audio->out + audio->out_head; 720 rc = wait_event_interruptible(audio->write_wait, 721 (frame->used == 0) 722 || (audio->stopped)); 723 dprintk("audamrnb_write() buffer available\n"); 724 if (rc < 0) 725 break; 726 if (audio->stopped) { 727 rc = -EBUSY; 728 break; 729 } 730 xfer = (count > frame->size) ? frame->size : count; 731 if (copy_from_user(frame->data, buf, xfer)) { 732 rc = -EFAULT; 733 break; 734 } 735 736 frame->used = xfer; 737 audio->out_head ^= 1; 738 count -= xfer; 739 buf += xfer; 740 741 audamrnb_send_data(audio, 0); 742 743 } 744 mutex_unlock(&audio->write_lock); 745 if (buf > start) 746 return buf - start; 747 return rc; 748} 749 750static int audamrnb_release(struct inode *inode, struct file *file) 751{ 752 struct audio *audio = file->private_data; 753 754 dprintk("audamrnb_release()\n"); 755 756 mutex_lock(&audio->lock); 757 audamrnb_disable(audio); 758 audamrnb_flush(audio); 759 audamrnb_flush_pcm_buf(audio); 760 msm_adsp_put(audio->audplay); 761 audio->audplay = NULL; 762 audio->opened = 0; 763 dma_free_coherent(NULL, DMASZ, audio->data, audio->phys); 764 audio->data = NULL; 765 if (audio->read_data != NULL) { 766 dma_free_coherent(NULL, 767 audio->in[0].size * audio->pcm_buf_count, 768 audio->read_data, audio->read_phys); 769 audio->read_data = NULL; 770 } 771 audio->pcm_feedback = 0; 772 mutex_unlock(&audio->lock); 773 return 0; 774} 775 776static struct audio the_amrnb_audio; 777 778static int audamrnb_open(struct inode *inode, struct file *file) 779{ 780 struct audio *audio = &the_amrnb_audio; 781 int rc; 782 783 mutex_lock(&audio->lock); 784 785 if (audio->opened) { 786 pr_err("audio: busy\n"); 787 rc = -EBUSY; 788 goto done; 789 } 790 791 if (!audio->data) { 792 audio->data = dma_alloc_coherent(NULL, DMASZ, 793 &audio->phys, GFP_KERNEL); 794 if (!audio->data) { 795 pr_err("audio: could not allocate DMA buffers\n"); 796 rc = -ENOMEM; 797 goto done; 798 } 799 } 800 801 rc = audmgr_open(&audio->audmgr); 802 if (rc) 803 goto done; 804 805 rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay, 806 &audplay_adsp_ops_amrnb, audio); 807 if (rc) { 808 pr_err("audio: failed to get audplay0 dsp module\n"); 809 audmgr_disable(&audio->audmgr); 810 dma_free_coherent(NULL, DMASZ, audio->data, audio->phys); 811 audio->data = NULL; 812 goto done; 813 } 814 815 audio->dec_id = 0; 816 817 audio->out[0].data = audio->data + 0; 818 audio->out[0].addr = audio->phys + 0; 819 audio->out[0].size = BUFSZ; 820 821 audio->out[1].data = audio->data + BUFSZ; 822 audio->out[1].addr = audio->phys + BUFSZ; 823 audio->out[1].size = BUFSZ; 824 825 audio->volume = 0x2000; /* Q13 1.0 */ 826 827 audamrnb_flush(audio); 828 829 file->private_data = audio; 830 audio->opened = 1; 831 rc = 0; 832done: 833 mutex_unlock(&audio->lock); 834 return rc; 835} 836 837static struct file_operations audio_amrnb_fops = { 838 .owner = THIS_MODULE, 839 .open = audamrnb_open, 840 .release = audamrnb_release, 841 .read = audamrnb_read, 842 .write = audamrnb_write, 843 .unlocked_ioctl = audamrnb_ioctl, 844}; 845 846struct miscdevice audio_amrnb_misc = { 847 .minor = MISC_DYNAMIC_MINOR, 848 .name = "msm_amrnb", 849 .fops = &audio_amrnb_fops, 850}; 851 852static int __init audamrnb_init(void) 853{ 854 mutex_init(&the_amrnb_audio.lock); 855 mutex_init(&the_amrnb_audio.write_lock); 856 mutex_init(&the_amrnb_audio.read_lock); 857 spin_lock_init(&the_amrnb_audio.dsp_lock); 858 init_waitqueue_head(&the_amrnb_audio.write_wait); 859 init_waitqueue_head(&the_amrnb_audio.read_wait); 860 the_amrnb_audio.read_data = NULL; 861 return misc_register(&audio_amrnb_misc); 862} 863 864static void __exit audamrnb_exit(void) 865{ 866 misc_deregister(&audio_amrnb_misc); 867} 868 869module_init(audamrnb_init); 870module_exit(audamrnb_exit); 871 872MODULE_DESCRIPTION("MSM AMR-NB driver"); 873MODULE_LICENSE("GPL v2"); 874MODULE_AUTHOR("QUALCOMM Inc"); 875