linux/drivers/staging/dream/qdsp5/audio_aac.c
<<
>>
Prefs
   1/* arch/arm/mach-msm/qdsp5/audio_aac.c
   2 *
   3 * aac audio decoder device
   4 *
   5 * Copyright (C) 2008 Google, Inc.
   6 * Copyright (C) 2008 HTC Corporation
   7 * Copyright (c) 2008-2009 QUALCOMM USA, INC.
   8 *
   9 * This software is licensed under the terms of the GNU General Public
  10 * License version 2, as published by the Free Software Foundation, and
  11 * may be copied, distributed, and modified under those terms.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 */
  19
  20#include <linux/module.h>
  21#include <linux/fs.h>
  22#include <linux/miscdevice.h>
  23#include <linux/uaccess.h>
  24#include <linux/kthread.h>
  25#include <linux/wait.h>
  26#include <linux/dma-mapping.h>
  27
  28#include <linux/delay.h>
  29
  30#include <asm/atomic.h>
  31#include <asm/ioctls.h>
  32#include "audmgr.h"
  33
  34#include <mach/msm_adsp.h>
  35#include <mach/msm_audio_aac.h>
  36#include <mach/qdsp5/qdsp5audppcmdi.h>
  37#include <mach/qdsp5/qdsp5audppmsg.h>
  38#include <mach/qdsp5/qdsp5audplaycmdi.h>
  39#include <mach/qdsp5/qdsp5audplaymsg.h>
  40
  41/* for queue ids - should be relative to module number*/
  42#include "adsp.h"
  43
  44#ifdef DEBUG
  45#define dprintk(format, arg...) \
  46printk(KERN_DEBUG format, ## arg)
  47#else
  48#define dprintk(format, arg...) do {} while (0)
  49#endif
  50
  51#define BUFSZ 32768
  52#define DMASZ (BUFSZ * 2)
  53
  54#define AUDPLAY_INVALID_READ_PTR_OFFSET 0xFFFF
  55#define AUDDEC_DEC_AAC 5
  56
  57#define PCM_BUFSZ_MIN 9600      /* Hold one stereo AAC frame */
  58#define PCM_BUF_MAX_COUNT 5     /* DSP only accepts 5 buffers at most
  59                                   but support 2 buffers currently */
  60#define ROUTING_MODE_FTRT 1
  61#define ROUTING_MODE_RT 2
  62/* Decoder status received from AUDPPTASK */
  63#define  AUDPP_DEC_STATUS_SLEEP 0
  64#define  AUDPP_DEC_STATUS_INIT  1
  65#define  AUDPP_DEC_STATUS_CFG   2
  66#define  AUDPP_DEC_STATUS_PLAY  3
  67
  68struct buffer {
  69        void *data;
  70        unsigned size;
  71        unsigned used;          /* Input usage actual DSP produced PCM size  */
  72        unsigned addr;
  73};
  74
  75struct audio {
  76        struct buffer out[2];
  77
  78        spinlock_t dsp_lock;
  79
  80        uint8_t out_head;
  81        uint8_t out_tail;
  82        uint8_t out_needed;     /* number of buffers the dsp is waiting for */
  83
  84        atomic_t out_bytes;
  85
  86        struct mutex lock;
  87        struct mutex write_lock;
  88        wait_queue_head_t write_wait;
  89
  90        /* Host PCM section */
  91        struct buffer in[PCM_BUF_MAX_COUNT];
  92        struct mutex read_lock;
  93        wait_queue_head_t read_wait;    /* Wait queue for read */
  94        char *read_data;        /* pointer to reader buffer */
  95        dma_addr_t read_phys;   /* physical address of reader buffer */
  96        uint8_t read_next;      /* index to input buffers to be read next */
  97        uint8_t fill_next;      /* index to buffer that DSP should be filling */
  98        uint8_t pcm_buf_count;  /* number of pcm buffer allocated */
  99        /* ---- End of Host PCM section */
 100
 101        struct msm_adsp_module *audplay;
 102
 103        /* configuration to use on next enable */
 104        uint32_t out_sample_rate;
 105        uint32_t out_channel_mode;
 106        struct msm_audio_aac_config aac_config;
 107        struct audmgr audmgr;
 108
 109        /* data allocated for various buffers */
 110        char *data;
 111        dma_addr_t phys;
 112
 113        int rflush; /* Read  flush */
 114        int wflush; /* Write flush */
 115        int opened;
 116        int enabled;
 117        int running;
 118        int stopped;    /* set when stopped, cleared on flush */
 119        int pcm_feedback;
 120        int buf_refresh;
 121
 122        int reserved; /* A byte is being reserved */
 123        char rsv_byte; /* Handle odd length user data */
 124
 125        unsigned volume;
 126
 127        uint16_t dec_id;
 128        uint32_t read_ptr_offset;
 129};
 130
 131static int auddec_dsp_config(struct audio *audio, int enable);
 132static void audpp_cmd_cfg_adec_params(struct audio *audio);
 133static void audpp_cmd_cfg_routing_mode(struct audio *audio);
 134static void audplay_send_data(struct audio *audio, unsigned needed);
 135static void audplay_config_hostpcm(struct audio *audio);
 136static void audplay_buffer_refresh(struct audio *audio);
 137static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
 138
 139/* must be called with audio->lock held */
 140static int audio_enable(struct audio *audio)
 141{
 142        struct audmgr_config cfg;
 143        int rc;
 144
 145        dprintk("audio_enable()\n");
 146
 147        if (audio->enabled)
 148                return 0;
 149
 150        audio->out_tail = 0;
 151        audio->out_needed = 0;
 152
 153        cfg.tx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
 154        cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_48000;
 155        cfg.def_method = RPC_AUD_DEF_METHOD_PLAYBACK;
 156        cfg.codec = RPC_AUD_DEF_CODEC_AAC;
 157        cfg.snd_method = RPC_SND_METHOD_MIDI;
 158
 159        rc = audmgr_enable(&audio->audmgr, &cfg);
 160        if (rc < 0)
 161                return rc;
 162
 163        if (msm_adsp_enable(audio->audplay)) {
 164                pr_err("audio: msm_adsp_enable(audplay) failed\n");
 165                audmgr_disable(&audio->audmgr);
 166                return -ENODEV;
 167        }
 168
 169        if (audpp_enable(audio->dec_id, audio_dsp_event, audio)) {
 170                pr_err("audio: audpp_enable() failed\n");
 171    msm_adsp_disable(audio->audplay);
 172                audmgr_disable(&audio->audmgr);
 173                return -ENODEV;
 174        }
 175        audio->enabled = 1;
 176        return 0;
 177}
 178
 179/* must be called with audio->lock held */
 180static int audio_disable(struct audio *audio)
 181{
 182        dprintk("audio_disable()\n");
 183        if (audio->enabled) {
 184                audio->enabled = 0;
 185                auddec_dsp_config(audio, 0);
 186                wake_up(&audio->write_wait);
 187                wake_up(&audio->read_wait);
 188                msm_adsp_disable(audio->audplay);
 189                audpp_disable(audio->dec_id, audio);
 190                audmgr_disable(&audio->audmgr);
 191                audio->out_needed = 0;
 192        }
 193        return 0;
 194}
 195
 196/* ------------------- dsp --------------------- */
 197static void audio_update_pcm_buf_entry(struct audio *audio, uint32_t *payload)
 198{
 199        uint8_t index;
 200        unsigned long flags;
 201
 202        if (audio->rflush)
 203                return;
 204
 205        spin_lock_irqsave(&audio->dsp_lock, flags);
 206        for (index = 0; index < payload[1]; index++) {
 207                if (audio->in[audio->fill_next].addr ==
 208                    payload[2 + index * 2]) {
 209                        dprintk("audio_update_pcm_buf_entry: in[%d] ready\n",
 210                                audio->fill_next);
 211                        audio->in[audio->fill_next].used =
 212                                payload[3 + index * 2];
 213                        if ((++audio->fill_next) == audio->pcm_buf_count)
 214                                audio->fill_next = 0;
 215
 216                } else {
 217                        pr_err
 218                            ("audio_update_pcm_buf_entry: expected=%x ret=%x\n"
 219                             , audio->in[audio->fill_next].addr,
 220                             payload[1 + index * 2]);
 221                        break;
 222                }
 223        }
 224        if (audio->in[audio->fill_next].used == 0) {
 225                audplay_buffer_refresh(audio);
 226        } else {
 227                dprintk("audio_update_pcm_buf_entry: read cannot keep up\n");
 228                audio->buf_refresh = 1;
 229        }
 230        wake_up(&audio->read_wait);
 231        spin_unlock_irqrestore(&audio->dsp_lock, flags);
 232
 233}
 234
 235static void audplay_dsp_event(void *data, unsigned id, size_t len,
 236                              void (*getevent) (void *ptr, size_t len))
 237{
 238        struct audio *audio = data;
 239        uint32_t msg[28];
 240        getevent(msg, sizeof(msg));
 241
 242        dprintk("audplay_dsp_event: msg_id=%x\n", id);
 243
 244        switch (id) {
 245        case AUDPLAY_MSG_DEC_NEEDS_DATA:
 246                audplay_send_data(audio, 1);
 247                break;
 248
 249        case AUDPLAY_MSG_BUFFER_UPDATE:
 250                audio_update_pcm_buf_entry(audio, msg);
 251                break;
 252
 253        default:
 254                pr_err("unexpected message from decoder \n");
 255        }
 256}
 257
 258static void audio_dsp_event(void *private, unsigned id, uint16_t *msg)
 259{
 260        struct audio *audio = private;
 261
 262        switch (id) {
 263        case AUDPP_MSG_STATUS_MSG:{
 264                        unsigned status = msg[1];
 265
 266                        switch (status) {
 267                        case AUDPP_DEC_STATUS_SLEEP:
 268                                dprintk("decoder status: sleep \n");
 269                                break;
 270
 271                        case AUDPP_DEC_STATUS_INIT:
 272                                dprintk("decoder status: init \n");
 273                                audpp_cmd_cfg_routing_mode(audio);
 274                                break;
 275
 276                        case AUDPP_DEC_STATUS_CFG:
 277                                dprintk("decoder status: cfg \n");
 278                                break;
 279                        case AUDPP_DEC_STATUS_PLAY:
 280                                dprintk("decoder status: play \n");
 281                                if (audio->pcm_feedback) {
 282                                        audplay_config_hostpcm(audio);
 283                                        audplay_buffer_refresh(audio);
 284                                }
 285                                break;
 286                        default:
 287                                pr_err("unknown decoder status \n");
 288                        }
 289                        break;
 290                }
 291        case AUDPP_MSG_CFG_MSG:
 292                if (msg[0] == AUDPP_MSG_ENA_ENA) {
 293                        dprintk("audio_dsp_event: CFG_MSG ENABLE\n");
 294                        auddec_dsp_config(audio, 1);
 295                        audio->out_needed = 0;
 296                        audio->running = 1;
 297                        audpp_set_volume_and_pan(audio->dec_id, audio->volume,
 298                                                 0);
 299                        audpp_avsync(audio->dec_id, 22050);
 300                } else if (msg[0] == AUDPP_MSG_ENA_DIS) {
 301                        dprintk("audio_dsp_event: CFG_MSG DISABLE\n");
 302                        audpp_avsync(audio->dec_id, 0);
 303                        audio->running = 0;
 304                } else {
 305                        pr_err("audio_dsp_event: CFG_MSG %d?\n", msg[0]);
 306                }
 307                break;
 308        case AUDPP_MSG_ROUTING_ACK:
 309                dprintk("audio_dsp_event: ROUTING_ACK mode=%d\n", msg[1]);
 310                audpp_cmd_cfg_adec_params(audio);
 311                break;
 312
 313        case AUDPP_MSG_FLUSH_ACK:
 314                dprintk("%s: FLUSH_ACK\n", __func__);
 315                audio->wflush = 0;
 316                audio->rflush = 0;
 317                if (audio->pcm_feedback)
 318                        audplay_buffer_refresh(audio);
 319                break;
 320
 321        default:
 322                pr_err("audio_dsp_event: UNKNOWN (%d)\n", id);
 323        }
 324
 325}
 326
 327struct msm_adsp_ops audplay_adsp_ops_aac = {
 328        .event = audplay_dsp_event,
 329};
 330
 331#define audplay_send_queue0(audio, cmd, len) \
 332        msm_adsp_write(audio->audplay, QDSP_uPAudPlay0BitStreamCtrlQueue, \
 333                       cmd, len)
 334
 335static int auddec_dsp_config(struct audio *audio, int enable)
 336{
 337        audpp_cmd_cfg_dec_type cmd;
 338
 339        memset(&cmd, 0, sizeof(cmd));
 340        cmd.cmd_id = AUDPP_CMD_CFG_DEC_TYPE;
 341        if (enable)
 342                cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC |
 343                    AUDPP_CMD_ENA_DEC_V | AUDDEC_DEC_AAC;
 344        else
 345                cmd.dec0_cfg = AUDPP_CMD_UPDATDE_CFG_DEC | AUDPP_CMD_DIS_DEC_V;
 346
 347        return audpp_send_queue1(&cmd, sizeof(cmd));
 348}
 349
 350static void audpp_cmd_cfg_adec_params(struct audio *audio)
 351{
 352        audpp_cmd_cfg_adec_params_aac cmd;
 353
 354        memset(&cmd, 0, sizeof(cmd));
 355        cmd.common.cmd_id = AUDPP_CMD_CFG_ADEC_PARAMS;
 356        cmd.common.length = AUDPP_CMD_CFG_ADEC_PARAMS_AAC_LEN;
 357        cmd.common.dec_id = audio->dec_id;
 358        cmd.common.input_sampling_frequency = audio->out_sample_rate;
 359        cmd.format = audio->aac_config.format;
 360        cmd.audio_object = audio->aac_config.audio_object;
 361        cmd.ep_config = audio->aac_config.ep_config;
 362        cmd.aac_section_data_resilience_flag =
 363                audio->aac_config.aac_section_data_resilience_flag;
 364        cmd.aac_scalefactor_data_resilience_flag =
 365                audio->aac_config.aac_scalefactor_data_resilience_flag;
 366        cmd.aac_spectral_data_resilience_flag =
 367                audio->aac_config.aac_spectral_data_resilience_flag;
 368        cmd.sbr_on_flag = audio->aac_config.sbr_on_flag;
 369        cmd.sbr_ps_on_flag = audio->aac_config.sbr_ps_on_flag;
 370        cmd.channel_configuration = audio->aac_config.channel_configuration;
 371
 372        audpp_send_queue2(&cmd, sizeof(cmd));
 373}
 374
 375static void audpp_cmd_cfg_routing_mode(struct audio *audio)
 376{
 377        struct audpp_cmd_routing_mode cmd;
 378        dprintk("audpp_cmd_cfg_routing_mode()\n");
 379        memset(&cmd, 0, sizeof(cmd));
 380        cmd.cmd_id = AUDPP_CMD_ROUTING_MODE;
 381        cmd.object_number = audio->dec_id;
 382        if (audio->pcm_feedback)
 383                cmd.routing_mode = ROUTING_MODE_FTRT;
 384        else
 385                cmd.routing_mode = ROUTING_MODE_RT;
 386
 387        audpp_send_queue1(&cmd, sizeof(cmd));
 388}
 389
 390static int audplay_dsp_send_data_avail(struct audio *audio,
 391                                       unsigned idx, unsigned len)
 392{
 393        audplay_cmd_bitstream_data_avail cmd;
 394
 395        cmd.cmd_id = AUDPLAY_CMD_BITSTREAM_DATA_AVAIL;
 396        cmd.decoder_id = audio->dec_id;
 397        cmd.buf_ptr = audio->out[idx].addr;
 398        cmd.buf_size = len / 2;
 399        cmd.partition_number = 0;
 400        return audplay_send_queue0(audio, &cmd, sizeof(cmd));
 401}
 402
 403static void audplay_buffer_refresh(struct audio *audio)
 404{
 405        struct audplay_cmd_buffer_refresh refresh_cmd;
 406
 407        refresh_cmd.cmd_id = AUDPLAY_CMD_BUFFER_REFRESH;
 408        refresh_cmd.num_buffers = 1;
 409        refresh_cmd.buf0_address = audio->in[audio->fill_next].addr;
 410        refresh_cmd.buf0_length = audio->in[audio->fill_next].size -
 411                (audio->in[audio->fill_next].size % 1024); /* AAC frame size */
 412        refresh_cmd.buf_read_count = 0;
 413        dprintk("audplay_buffer_fresh: buf0_addr=%x buf0_len=%d\n",
 414                refresh_cmd.buf0_address, refresh_cmd.buf0_length);
 415        (void)audplay_send_queue0(audio, &refresh_cmd, sizeof(refresh_cmd));
 416}
 417
 418static void audplay_config_hostpcm(struct audio *audio)
 419{
 420        struct audplay_cmd_hpcm_buf_cfg cfg_cmd;
 421
 422        dprintk("audplay_config_hostpcm()\n");
 423        cfg_cmd.cmd_id = AUDPLAY_CMD_HPCM_BUF_CFG;
 424        cfg_cmd.max_buffers = audio->pcm_buf_count;
 425        cfg_cmd.byte_swap = 0;
 426        cfg_cmd.hostpcm_config = (0x8000) | (0x4000);
 427        cfg_cmd.feedback_frequency = 1;
 428        cfg_cmd.partition_number = 0;
 429        (void)audplay_send_queue0(audio, &cfg_cmd, sizeof(cfg_cmd));
 430
 431}
 432
 433static void audplay_send_data(struct audio *audio, unsigned needed)
 434{
 435        struct buffer *frame;
 436        unsigned long flags;
 437
 438        spin_lock_irqsave(&audio->dsp_lock, flags);
 439        if (!audio->running)
 440                goto done;
 441
 442        if (needed && !audio->wflush) {
 443                /* We were called from the callback because the DSP
 444                 * requested more data.  Note that the DSP does want
 445                 * more data, and if a buffer was in-flight, mark it
 446                 * as available (since the DSP must now be done with
 447                 * it).
 448                 */
 449                audio->out_needed = 1;
 450                frame = audio->out + audio->out_tail;
 451                if (frame->used == 0xffffffff) {
 452                        dprintk("frame %d free\n", audio->out_tail);
 453                        frame->used = 0;
 454                        audio->out_tail ^= 1;
 455                        wake_up(&audio->write_wait);
 456                }
 457        }
 458
 459        if (audio->out_needed) {
 460                /* If the DSP currently wants data and we have a
 461                 * buffer available, we will send it and reset
 462                 * the needed flag.  We'll mark the buffer as in-flight
 463                 * so that it won't be recycled until the next buffer
 464                 * is requested
 465                 */
 466
 467                frame = audio->out + audio->out_tail;
 468                if (frame->used) {
 469                        BUG_ON(frame->used == 0xffffffff);
 470/*                      printk("frame %d busy\n", audio->out_tail); */
 471                        audplay_dsp_send_data_avail(audio, audio->out_tail,
 472                                                    frame->used);
 473                        frame->used = 0xffffffff;
 474                        audio->out_needed = 0;
 475                }
 476        }
 477 done:
 478        spin_unlock_irqrestore(&audio->dsp_lock, flags);
 479}
 480
 481/* ------------------- device --------------------- */
 482
 483static void audio_flush(struct audio *audio)
 484{
 485        audio->out[0].used = 0;
 486        audio->out[1].used = 0;
 487        audio->out_head = 0;
 488        audio->out_tail = 0;
 489        audio->reserved = 0;
 490        audio->out_needed = 0;
 491        atomic_set(&audio->out_bytes, 0);
 492}
 493
 494static void audio_flush_pcm_buf(struct audio *audio)
 495{
 496        uint8_t index;
 497
 498        for (index = 0; index < PCM_BUF_MAX_COUNT; index++)
 499                audio->in[index].used = 0;
 500        audio->buf_refresh = 0;
 501        audio->read_next = 0;
 502        audio->fill_next = 0;
 503}
 504
 505static int audaac_validate_usr_config(struct msm_audio_aac_config *config)
 506{
 507        int ret_val = -1;
 508
 509        if (config->format != AUDIO_AAC_FORMAT_ADTS &&
 510                config->format != AUDIO_AAC_FORMAT_RAW &&
 511                config->format != AUDIO_AAC_FORMAT_PSUEDO_RAW &&
 512                config->format != AUDIO_AAC_FORMAT_LOAS)
 513                goto done;
 514
 515        if (config->audio_object != AUDIO_AAC_OBJECT_LC &&
 516                config->audio_object != AUDIO_AAC_OBJECT_LTP &&
 517                config->audio_object != AUDIO_AAC_OBJECT_ERLC)
 518                goto done;
 519
 520        if (config->audio_object == AUDIO_AAC_OBJECT_ERLC) {
 521                if (config->ep_config > 3)
 522                        goto done;
 523                if (config->aac_scalefactor_data_resilience_flag !=
 524                        AUDIO_AAC_SCA_DATA_RES_OFF &&
 525                        config->aac_scalefactor_data_resilience_flag !=
 526                        AUDIO_AAC_SCA_DATA_RES_ON)
 527                        goto done;
 528                if (config->aac_section_data_resilience_flag !=
 529                        AUDIO_AAC_SEC_DATA_RES_OFF &&
 530                        config->aac_section_data_resilience_flag !=
 531                        AUDIO_AAC_SEC_DATA_RES_ON)
 532                        goto done;
 533                if (config->aac_spectral_data_resilience_flag !=
 534                        AUDIO_AAC_SPEC_DATA_RES_OFF &&
 535                        config->aac_spectral_data_resilience_flag !=
 536                        AUDIO_AAC_SPEC_DATA_RES_ON)
 537                        goto done;
 538        } else {
 539                config->aac_section_data_resilience_flag =
 540                        AUDIO_AAC_SEC_DATA_RES_OFF;
 541                config->aac_scalefactor_data_resilience_flag =
 542                        AUDIO_AAC_SCA_DATA_RES_OFF;
 543                config->aac_spectral_data_resilience_flag =
 544                        AUDIO_AAC_SPEC_DATA_RES_OFF;
 545        }
 546
 547        if (config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_OFF &&
 548                config->sbr_on_flag != AUDIO_AAC_SBR_ON_FLAG_ON)
 549                goto done;
 550
 551        if (config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_OFF &&
 552                config->sbr_ps_on_flag != AUDIO_AAC_SBR_PS_ON_FLAG_ON)
 553                goto done;
 554
 555        if (config->dual_mono_mode > AUDIO_AAC_DUAL_MONO_PL_SR)
 556                goto done;
 557
 558        if (config->channel_configuration > 2)
 559                goto done;
 560
 561        ret_val = 0;
 562 done:
 563        return ret_val;
 564}
 565
 566static void audio_ioport_reset(struct audio *audio)
 567{
 568        /* Make sure read/write thread are free from
 569         * sleep and knowing that system is not able
 570         * to process io request at the moment
 571         */
 572        wake_up(&audio->write_wait);
 573        mutex_lock(&audio->write_lock);
 574        audio_flush(audio);
 575        mutex_unlock(&audio->write_lock);
 576        wake_up(&audio->read_wait);
 577        mutex_lock(&audio->read_lock);
 578        audio_flush_pcm_buf(audio);
 579        mutex_unlock(&audio->read_lock);
 580}
 581
 582static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 583{
 584        struct audio *audio = file->private_data;
 585        int rc = 0;
 586
 587        dprintk("audio_ioctl() cmd = %d\n", cmd);
 588
 589        if (cmd == AUDIO_GET_STATS) {
 590                struct msm_audio_stats stats;
 591                stats.byte_count = audpp_avsync_byte_count(audio->dec_id);
 592                stats.sample_count = audpp_avsync_sample_count(audio->dec_id);
 593                if (copy_to_user((void *)arg, &stats, sizeof(stats)))
 594                        return -EFAULT;
 595                return 0;
 596        }
 597        if (cmd == AUDIO_SET_VOLUME) {
 598                unsigned long flags;
 599                spin_lock_irqsave(&audio->dsp_lock, flags);
 600                audio->volume = arg;
 601                if (audio->running)
 602                        audpp_set_volume_and_pan(audio->dec_id, arg, 0);
 603                spin_unlock_irqrestore(&audio->dsp_lock, flags);
 604                return 0;
 605        }
 606        mutex_lock(&audio->lock);
 607        switch (cmd) {
 608        case AUDIO_START:
 609                rc = audio_enable(audio);
 610                break;
 611        case AUDIO_STOP:
 612                rc = audio_disable(audio);
 613                audio->stopped = 1;
 614                audio_ioport_reset(audio);
 615                audio->stopped = 0;
 616                break;
 617        case AUDIO_FLUSH:
 618                dprintk("%s: AUDIO_FLUSH\n", __func__);
 619                audio->rflush = 1;
 620                audio->wflush = 1;
 621                audio_ioport_reset(audio);
 622                if (audio->running)
 623                        audpp_flush(audio->dec_id);
 624                else {
 625                        audio->rflush = 0;
 626                        audio->wflush = 0;
 627                }
 628                break;
 629
 630        case AUDIO_SET_CONFIG:{
 631                        struct msm_audio_config config;
 632
 633                        if (copy_from_user
 634                            (&config, (void *)arg, sizeof(config))) {
 635                                rc = -EFAULT;
 636                                break;
 637                        }
 638
 639                        if (config.channel_count == 1) {
 640                                config.channel_count =
 641                                    AUDPP_CMD_PCM_INTF_MONO_V;
 642                        } else if (config.channel_count == 2) {
 643                                config.channel_count =
 644                                    AUDPP_CMD_PCM_INTF_STEREO_V;
 645                        } else {
 646                                rc = -EINVAL;
 647                                break;
 648                        }
 649
 650                        audio->out_sample_rate = config.sample_rate;
 651                        audio->out_channel_mode = config.channel_count;
 652                        rc = 0;
 653                        break;
 654                }
 655        case AUDIO_GET_CONFIG:{
 656                        struct msm_audio_config config;
 657                        config.buffer_size = BUFSZ;
 658                        config.buffer_count = 2;
 659                        config.sample_rate = audio->out_sample_rate;
 660                        if (audio->out_channel_mode ==
 661                            AUDPP_CMD_PCM_INTF_MONO_V) {
 662                                config.channel_count = 1;
 663                        } else {
 664                                config.channel_count = 2;
 665                        }
 666                        config.unused[0] = 0;
 667                        config.unused[1] = 0;
 668                        config.unused[2] = 0;
 669                        config.unused[3] = 0;
 670                        if (copy_to_user((void *)arg, &config,
 671                                         sizeof(config)))
 672                                rc = -EFAULT;
 673                        else
 674                                rc = 0;
 675
 676                        break;
 677                }
 678        case AUDIO_GET_AAC_CONFIG:{
 679                        if (copy_to_user((void *)arg, &audio->aac_config,
 680                                sizeof(audio->aac_config)))
 681                                rc = -EFAULT;
 682                        else
 683                                rc = 0;
 684                        break;
 685                }
 686        case AUDIO_SET_AAC_CONFIG:{
 687                        struct msm_audio_aac_config usr_config;
 688
 689                        if (copy_from_user
 690                                (&usr_config, (void *)arg,
 691                                        sizeof(usr_config))) {
 692                                rc = -EFAULT;
 693                                break;
 694                        }
 695
 696                        if (audaac_validate_usr_config(&usr_config) == 0) {
 697                                audio->aac_config = usr_config;
 698                                rc = 0;
 699                        } else
 700                                rc = -EINVAL;
 701
 702                        break;
 703                }
 704        case AUDIO_GET_PCM_CONFIG:{
 705                        struct msm_audio_pcm_config config;
 706                        config.pcm_feedback = 0;
 707                        config.buffer_count = PCM_BUF_MAX_COUNT;
 708                        config.buffer_size = PCM_BUFSZ_MIN;
 709                        if (copy_to_user((void *)arg, &config,
 710                                         sizeof(config)))
 711                                rc = -EFAULT;
 712                        else
 713                                rc = 0;
 714                        break;
 715                }
 716        case AUDIO_SET_PCM_CONFIG:{
 717                        struct msm_audio_pcm_config config;
 718                        if (copy_from_user
 719                            (&config, (void *)arg, sizeof(config))) {
 720                                rc = -EFAULT;
 721                                break;
 722                        }
 723                        if ((config.buffer_count > PCM_BUF_MAX_COUNT) ||
 724                            (config.buffer_count == 1))
 725                                config.buffer_count = PCM_BUF_MAX_COUNT;
 726
 727                        if (config.buffer_size < PCM_BUFSZ_MIN)
 728                                config.buffer_size = PCM_BUFSZ_MIN;
 729
 730                        /* Check if pcm feedback is required */
 731                        if ((config.pcm_feedback) && (!audio->read_data)) {
 732                                dprintk("ioctl: allocate PCM buffer %d\n",
 733                                        config.buffer_count *
 734                                        config.buffer_size);
 735                                audio->read_data =
 736                                    dma_alloc_coherent(NULL,
 737                                                       config.buffer_size *
 738                                                       config.buffer_count,
 739                                                       &audio->read_phys,
 740                                                       GFP_KERNEL);
 741                                if (!audio->read_data) {
 742                                        pr_err("audio_aac: buf alloc fail\n");
 743                                        rc = -1;
 744                                } else {
 745                                        uint8_t index;
 746                                        uint32_t offset = 0;
 747                                        audio->pcm_feedback = 1;
 748                                        audio->buf_refresh = 0;
 749                                        audio->pcm_buf_count =
 750                                            config.buffer_count;
 751                                        audio->read_next = 0;
 752                                        audio->fill_next = 0;
 753
 754                                        for (index = 0;
 755                                             index < config.buffer_count;
 756                                             index++) {
 757                                                audio->in[index].data =
 758                                                    audio->read_data + offset;
 759                                                audio->in[index].addr =
 760                                                    audio->read_phys + offset;
 761                                                audio->in[index].size =
 762                                                    config.buffer_size;
 763                                                audio->in[index].used = 0;
 764                                                offset += config.buffer_size;
 765                                        }
 766                                        rc = 0;
 767                                }
 768                        } else {
 769                                rc = 0;
 770                        }
 771                        break;
 772                }
 773        case AUDIO_PAUSE:
 774                dprintk("%s: AUDIO_PAUSE %ld\n", __func__, arg);
 775                rc = audpp_pause(audio->dec_id, (int) arg);
 776                break;
 777        default:
 778                rc = -EINVAL;
 779        }
 780        mutex_unlock(&audio->lock);
 781        return rc;
 782}
 783
 784static ssize_t audio_read(struct file *file, char __user *buf, size_t count,
 785                          loff_t *pos)
 786{
 787        struct audio *audio = file->private_data;
 788        const char __user *start = buf;
 789        int rc = 0;
 790
 791        if (!audio->pcm_feedback)
 792                return 0; /* PCM feedback is not enabled. Nothing to read */
 793
 794        mutex_lock(&audio->read_lock);
 795        dprintk("audio_read() %d \n", count);
 796        while (count > 0) {
 797                rc = wait_event_interruptible(audio->read_wait,
 798                                              (audio->in[audio->read_next].
 799                                                used > 0) || (audio->stopped)
 800                                                || (audio->rflush));
 801
 802                if (rc < 0)
 803                        break;
 804
 805                if (audio->stopped || audio->rflush) {
 806                        rc = -EBUSY;
 807                        break;
 808                }
 809
 810                if (count < audio->in[audio->read_next].used) {
 811                        /* Read must happen in frame boundary. Since driver
 812                           does not know frame size, read count must be greater
 813                           or equal to size of PCM samples */
 814                        dprintk("audio_read: no partial frame done reading\n");
 815                        break;
 816                } else {
 817                        dprintk("audio_read: read from in[%d]\n",
 818                                audio->read_next);
 819                        if (copy_to_user
 820                            (buf, audio->in[audio->read_next].data,
 821                             audio->in[audio->read_next].used)) {
 822                                pr_err("audio_read: invalid addr %x \n",
 823                                       (unsigned int)buf);
 824                                rc = -EFAULT;
 825                                break;
 826                        }
 827                        count -= audio->in[audio->read_next].used;
 828                        buf += audio->in[audio->read_next].used;
 829                        audio->in[audio->read_next].used = 0;
 830                        if ((++audio->read_next) == audio->pcm_buf_count)
 831                                audio->read_next = 0;
 832                        if (audio->in[audio->read_next].used == 0)
 833                                break; /* No data ready at this moment
 834                                        * Exit while loop to prevent
 835                                        * output thread sleep too long
 836                                        */
 837                }
 838        }
 839
 840        /* don't feed output buffer to HW decoder during flushing
 841         * buffer refresh command will be sent once flush completes
 842         * send buf refresh command here can confuse HW decoder
 843         */
 844        if (audio->buf_refresh && !audio->rflush) {
 845                audio->buf_refresh = 0;
 846                dprintk("audio_read: kick start pcm feedback again\n");
 847                audplay_buffer_refresh(audio);
 848        }
 849
 850        mutex_unlock(&audio->read_lock);
 851
 852        if (buf > start)
 853                rc = buf - start;
 854
 855        dprintk("audio_read: read %d bytes\n", rc);
 856        return rc;
 857}
 858
 859static ssize_t audio_write(struct file *file, const char __user *buf,
 860                           size_t count, loff_t *pos)
 861{
 862        struct audio *audio = file->private_data;
 863        const char __user *start = buf;
 864        struct buffer *frame;
 865        size_t xfer;
 866        char *cpy_ptr;
 867        int rc = 0;
 868        unsigned dsize;
 869
 870        mutex_lock(&audio->write_lock);
 871        while (count > 0) {
 872                frame = audio->out + audio->out_head;
 873                cpy_ptr = frame->data;
 874                dsize = 0;
 875                rc = wait_event_interruptible(audio->write_wait,
 876                                              (frame->used == 0)
 877                                                || (audio->stopped)
 878                                                || (audio->wflush));
 879                if (rc < 0)
 880                        break;
 881                if (audio->stopped || audio->wflush) {
 882                        rc = -EBUSY;
 883                        break;
 884                }
 885
 886                if (audio->reserved) {
 887                        dprintk("%s: append reserved byte %x\n",
 888                                __func__, audio->rsv_byte);
 889                        *cpy_ptr = audio->rsv_byte;
 890                        xfer = (count > (frame->size - 1)) ?
 891                                frame->size - 1 : count;
 892                        cpy_ptr++;
 893                        dsize = 1;
 894                        audio->reserved = 0;
 895                } else
 896                        xfer = (count > frame->size) ? frame->size : count;
 897
 898                if (copy_from_user(cpy_ptr, buf, xfer)) {
 899                        rc = -EFAULT;
 900                        break;
 901                }
 902
 903                dsize += xfer;
 904                if (dsize & 1) {
 905                        audio->rsv_byte = ((char *) frame->data)[dsize - 1];
 906                        dprintk("%s: odd length buf reserve last byte %x\n",
 907                                __func__, audio->rsv_byte);
 908                        audio->reserved = 1;
 909                        dsize--;
 910                }
 911                count -= xfer;
 912                buf += xfer;
 913
 914                if (dsize > 0) {
 915                        audio->out_head ^= 1;
 916                        frame->used = dsize;
 917                        audplay_send_data(audio, 0);
 918                }
 919        }
 920        mutex_unlock(&audio->write_lock);
 921        if (buf > start)
 922                return buf - start;
 923        return rc;
 924}
 925
 926static int audio_release(struct inode *inode, struct file *file)
 927{
 928        struct audio *audio = file->private_data;
 929
 930        dprintk("audio_release()\n");
 931
 932        mutex_lock(&audio->lock);
 933        audio_disable(audio);
 934        audio_flush(audio);
 935        audio_flush_pcm_buf(audio);
 936        msm_adsp_put(audio->audplay);
 937        audio->audplay = NULL;
 938        audio->opened = 0;
 939        audio->reserved = 0;
 940        dma_free_coherent(NULL, DMASZ, audio->data, audio->phys);
 941        audio->data = NULL;
 942        if (audio->read_data != NULL) {
 943                dma_free_coherent(NULL,
 944                                  audio->in[0].size * audio->pcm_buf_count,
 945                                  audio->read_data, audio->read_phys);
 946                audio->read_data = NULL;
 947        }
 948        audio->pcm_feedback = 0;
 949        mutex_unlock(&audio->lock);
 950        return 0;
 951}
 952
 953static struct audio the_aac_audio;
 954
 955static int audio_open(struct inode *inode, struct file *file)
 956{
 957        struct audio *audio = &the_aac_audio;
 958        int rc;
 959
 960        mutex_lock(&audio->lock);
 961
 962        if (audio->opened) {
 963                pr_err("audio: busy\n");
 964                rc = -EBUSY;
 965                goto done;
 966        }
 967
 968        if (!audio->data) {
 969                audio->data = dma_alloc_coherent(NULL, DMASZ,
 970                                                 &audio->phys, GFP_KERNEL);
 971                if (!audio->data) {
 972                        pr_err("audio: could not allocate DMA buffers\n");
 973                        rc = -ENOMEM;
 974                        goto done;
 975                }
 976        }
 977
 978        rc = audmgr_open(&audio->audmgr);
 979        if (rc)
 980                goto done;
 981
 982        rc = msm_adsp_get("AUDPLAY0TASK", &audio->audplay,
 983                          &audplay_adsp_ops_aac, audio);
 984        if (rc) {
 985                pr_err("audio: failed to get audplay0 dsp module\n");
 986                goto done;
 987        }
 988        audio->out_sample_rate = 44100;
 989        audio->out_channel_mode = AUDPP_CMD_PCM_INTF_STEREO_V;
 990        audio->aac_config.format = AUDIO_AAC_FORMAT_ADTS;
 991        audio->aac_config.audio_object = AUDIO_AAC_OBJECT_LC;
 992        audio->aac_config.ep_config = 0;
 993        audio->aac_config.aac_section_data_resilience_flag =
 994                AUDIO_AAC_SEC_DATA_RES_OFF;
 995        audio->aac_config.aac_scalefactor_data_resilience_flag =
 996                AUDIO_AAC_SCA_DATA_RES_OFF;
 997        audio->aac_config.aac_spectral_data_resilience_flag =
 998                AUDIO_AAC_SPEC_DATA_RES_OFF;
 999        audio->aac_config.sbr_on_flag = AUDIO_AAC_SBR_ON_FLAG_ON;
1000        audio->aac_config.sbr_ps_on_flag = AUDIO_AAC_SBR_PS_ON_FLAG_ON;
1001        audio->aac_config.dual_mono_mode = AUDIO_AAC_DUAL_MONO_PL_SR;
1002        audio->aac_config.channel_configuration = 2;
1003        audio->dec_id = 0;
1004
1005        audio->out[0].data = audio->data + 0;
1006        audio->out[0].addr = audio->phys + 0;
1007        audio->out[0].size = BUFSZ;
1008
1009        audio->out[1].data = audio->data + BUFSZ;
1010        audio->out[1].addr = audio->phys + BUFSZ;
1011        audio->out[1].size = BUFSZ;
1012
1013        audio->volume = 0x2000; /* Q13 1.0 */
1014
1015        audio_flush(audio);
1016
1017        file->private_data = audio;
1018        audio->opened = 1;
1019        rc = 0;
1020done:
1021        mutex_unlock(&audio->lock);
1022        return rc;
1023}
1024
1025static struct file_operations audio_aac_fops = {
1026        .owner = THIS_MODULE,
1027        .open = audio_open,
1028        .release = audio_release,
1029        .read = audio_read,
1030        .write = audio_write,
1031        .unlocked_ioctl = audio_ioctl,
1032};
1033
1034struct miscdevice audio_aac_misc = {
1035        .minor = MISC_DYNAMIC_MINOR,
1036        .name = "msm_aac",
1037        .fops = &audio_aac_fops,
1038};
1039
1040static int __init audio_init(void)
1041{
1042        mutex_init(&the_aac_audio.lock);
1043        mutex_init(&the_aac_audio.write_lock);
1044        mutex_init(&the_aac_audio.read_lock);
1045        spin_lock_init(&the_aac_audio.dsp_lock);
1046        init_waitqueue_head(&the_aac_audio.write_wait);
1047        init_waitqueue_head(&the_aac_audio.read_wait);
1048        the_aac_audio.read_data = NULL;
1049        return misc_register(&audio_aac_misc);
1050}
1051
1052device_initcall(audio_init);
1053