linux/drivers/staging/dream/qdsp5/audio_in.c
<<
>>
Prefs
   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
  27#include <linux/delay.h>
  28
  29#include <linux/msm_audio.h>
  30
  31#include <asm/atomic.h>
  32#include <asm/ioctls.h>
  33#include <mach/msm_adsp.h>
  34#include <mach/msm_rpcrouter.h>
  35
  36#include "audmgr.h"
  37
  38#include <mach/qdsp5/qdsp5audpreproccmdi.h>
  39#include <mach/qdsp5/qdsp5audpreprocmsg.h>
  40#include <mach/qdsp5/qdsp5audreccmdi.h>
  41#include <mach/qdsp5/qdsp5audrecmsg.h>
  42
  43/* for queue ids - should be relative to module number*/
  44#include "adsp.h"
  45
  46/* FRAME_NUM must be a power of two */
  47#define FRAME_NUM               (8)
  48#define FRAME_SIZE              (2052 * 2)
  49#define MONO_DATA_SIZE          (2048)
  50#define STEREO_DATA_SIZE        (MONO_DATA_SIZE * 2)
  51#define DMASZ                   (FRAME_SIZE * FRAME_NUM)
  52
  53#define AGC_PARAM_SIZE          (20)
  54#define NS_PARAM_SIZE           (6)
  55#define IIR_PARAM_SIZE          (48)
  56#define DEBUG                   (0)
  57
  58#define AGC_ENABLE   0x0001
  59#define NS_ENABLE    0x0002
  60#define IIR_ENABLE   0x0004
  61
  62struct tx_agc_config {
  63        uint16_t agc_params[AGC_PARAM_SIZE];
  64};
  65
  66struct ns_config {
  67        uint16_t ns_params[NS_PARAM_SIZE];
  68};
  69
  70struct tx_iir_filter {
  71        uint16_t num_bands;
  72        uint16_t iir_params[IIR_PARAM_SIZE];
  73};
  74
  75struct audpre_cmd_iir_config_type {
  76        uint16_t cmd_id;
  77        uint16_t active_flag;
  78        uint16_t num_bands;
  79        uint16_t iir_params[IIR_PARAM_SIZE];
  80};
  81
  82struct buffer {
  83        void *data;
  84        uint32_t size;
  85        uint32_t read;
  86        uint32_t addr;
  87};
  88
  89struct audio_in {
  90        struct buffer in[FRAME_NUM];
  91
  92        spinlock_t dsp_lock;
  93
  94        atomic_t in_bytes;
  95
  96        struct mutex lock;
  97        struct mutex read_lock;
  98        wait_queue_head_t wait;
  99
 100        struct msm_adsp_module *audpre;
 101        struct msm_adsp_module *audrec;
 102
 103        /* configuration to use on next enable */
 104        uint32_t samp_rate;
 105        uint32_t channel_mode;
 106        uint32_t buffer_size; /* 2048 for mono, 4096 for stereo */
 107        uint32_t type; /* 0 for PCM ,1 for AAC */
 108        uint32_t dsp_cnt;
 109        uint32_t in_head; /* next buffer dsp will write */
 110        uint32_t in_tail; /* next buffer read() will read */
 111        uint32_t in_count; /* number of buffers available to read() */
 112
 113        unsigned short samp_rate_index;
 114
 115        struct audmgr audmgr;
 116
 117        /* data allocated for various buffers */
 118        char *data;
 119        dma_addr_t phys;
 120
 121        int opened;
 122        int enabled;
 123        int running;
 124        int stopped; /* set when stopped, cleared on flush */
 125
 126        /* audpre settings */
 127        int agc_enable;
 128        struct tx_agc_config agc;
 129
 130        int ns_enable;
 131        struct ns_config ns;
 132
 133        int iir_enable;
 134        struct tx_iir_filter iir;
 135};
 136
 137static int audio_in_dsp_enable(struct audio_in *audio, int enable);
 138static int audio_in_encoder_config(struct audio_in *audio);
 139static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt);
 140static void audio_flush(struct audio_in *audio);
 141static int audio_dsp_set_agc(struct audio_in *audio);
 142static int audio_dsp_set_ns(struct audio_in *audio);
 143static int audio_dsp_set_tx_iir(struct audio_in *audio);
 144
 145static unsigned convert_dsp_samp_index(unsigned index)
 146{
 147        switch (index) {
 148        case 48000:     return AUDREC_CMD_SAMP_RATE_INDX_48000;
 149        case 44100:     return AUDREC_CMD_SAMP_RATE_INDX_44100;
 150        case 32000:     return AUDREC_CMD_SAMP_RATE_INDX_32000;
 151        case 24000:     return AUDREC_CMD_SAMP_RATE_INDX_24000;
 152        case 22050:     return AUDREC_CMD_SAMP_RATE_INDX_22050;
 153        case 16000:     return AUDREC_CMD_SAMP_RATE_INDX_16000;
 154        case 12000:     return AUDREC_CMD_SAMP_RATE_INDX_12000;
 155        case 11025:     return AUDREC_CMD_SAMP_RATE_INDX_11025;
 156        case 8000:      return AUDREC_CMD_SAMP_RATE_INDX_8000;
 157        default:        return AUDREC_CMD_SAMP_RATE_INDX_11025;
 158        }
 159}
 160
 161static unsigned convert_samp_rate(unsigned hz)
 162{
 163        switch (hz) {
 164        case 48000: return RPC_AUD_DEF_SAMPLE_RATE_48000;
 165        case 44100: return RPC_AUD_DEF_SAMPLE_RATE_44100;
 166        case 32000: return RPC_AUD_DEF_SAMPLE_RATE_32000;
 167        case 24000: return RPC_AUD_DEF_SAMPLE_RATE_24000;
 168        case 22050: return RPC_AUD_DEF_SAMPLE_RATE_22050;
 169        case 16000: return RPC_AUD_DEF_SAMPLE_RATE_16000;
 170        case 12000: return RPC_AUD_DEF_SAMPLE_RATE_12000;
 171        case 11025: return RPC_AUD_DEF_SAMPLE_RATE_11025;
 172        case 8000:  return RPC_AUD_DEF_SAMPLE_RATE_8000;
 173        default:    return RPC_AUD_DEF_SAMPLE_RATE_11025;
 174        }
 175}
 176
 177static unsigned convert_samp_index(unsigned index)
 178{
 179        switch (index) {
 180        case RPC_AUD_DEF_SAMPLE_RATE_48000:     return 48000;
 181        case RPC_AUD_DEF_SAMPLE_RATE_44100:     return 44100;
 182        case RPC_AUD_DEF_SAMPLE_RATE_32000:     return 32000;
 183        case RPC_AUD_DEF_SAMPLE_RATE_24000:     return 24000;
 184        case RPC_AUD_DEF_SAMPLE_RATE_22050:     return 22050;
 185        case RPC_AUD_DEF_SAMPLE_RATE_16000:     return 16000;
 186        case RPC_AUD_DEF_SAMPLE_RATE_12000:     return 12000;
 187        case RPC_AUD_DEF_SAMPLE_RATE_11025:     return 11025;
 188        case RPC_AUD_DEF_SAMPLE_RATE_8000:      return 8000;
 189        default:                                return 11025;
 190        }
 191}
 192
 193/* must be called with audio->lock held */
 194static int audio_in_enable(struct audio_in *audio)
 195{
 196        struct audmgr_config cfg;
 197        int rc;
 198
 199        if (audio->enabled)
 200                return 0;
 201
 202        cfg.tx_rate = audio->samp_rate;
 203        cfg.rx_rate = RPC_AUD_DEF_SAMPLE_RATE_NONE;
 204        cfg.def_method = RPC_AUD_DEF_METHOD_RECORD;
 205        if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
 206                cfg.codec = RPC_AUD_DEF_CODEC_PCM;
 207        else
 208                cfg.codec = RPC_AUD_DEF_CODEC_AAC;
 209        cfg.snd_method = RPC_SND_METHOD_MIDI;
 210
 211        rc = audmgr_enable(&audio->audmgr, &cfg);
 212        if (rc < 0)
 213                return rc;
 214
 215        if (msm_adsp_enable(audio->audpre)) {
 216                pr_err("audrec: msm_adsp_enable(audpre) failed\n");
 217                return -ENODEV;
 218        }
 219        if (msm_adsp_enable(audio->audrec)) {
 220                pr_err("audrec: msm_adsp_enable(audrec) failed\n");
 221                return -ENODEV;
 222        }
 223
 224        audio->enabled = 1;
 225        audio_in_dsp_enable(audio, 1);
 226
 227        return 0;
 228}
 229
 230/* must be called with audio->lock held */
 231static int audio_in_disable(struct audio_in *audio)
 232{
 233        if (audio->enabled) {
 234                audio->enabled = 0;
 235
 236                audio_in_dsp_enable(audio, 0);
 237
 238                wake_up(&audio->wait);
 239
 240                msm_adsp_disable(audio->audrec);
 241                msm_adsp_disable(audio->audpre);
 242                audmgr_disable(&audio->audmgr);
 243        }
 244        return 0;
 245}
 246
 247/* ------------------- dsp --------------------- */
 248static void audpre_dsp_event(void *data, unsigned id, size_t len,
 249                            void (*getevent)(void *ptr, size_t len))
 250{
 251        uint16_t msg[2];
 252        getevent(msg, sizeof(msg));
 253
 254        switch (id) {
 255        case AUDPREPROC_MSG_CMD_CFG_DONE_MSG:
 256                pr_info("audpre: type %d, status_flag %d\n", msg[0], msg[1]);
 257                break;
 258        case AUDPREPROC_MSG_ERROR_MSG_ID:
 259                pr_info("audpre: err_index %d\n", msg[0]);
 260                break;
 261        default:
 262                pr_err("audpre: unknown event %d\n", id);
 263        }
 264}
 265
 266struct audio_frame {
 267        uint16_t count_low;
 268        uint16_t count_high;
 269        uint16_t bytes;
 270        uint16_t unknown;
 271        unsigned char samples[];
 272} __attribute__((packed));
 273
 274static void audio_in_get_dsp_frames(struct audio_in *audio)
 275{
 276        struct audio_frame *frame;
 277        uint32_t index;
 278        unsigned long flags;
 279
 280        index = audio->in_head;
 281
 282        /* XXX check for bogus frame size? */
 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        /* FIXME have no idea why cmd.rec_quality is fixed
 528         * as 0x1C00 from sample code
 529         */
 530        cmd.rec_quality = 0x1C00;
 531
 532        /* prepare buffer pointers:
 533         * Mono: 1024 samples + 4 halfword header
 534         * Stereo: 2048 samples + 4 halfword header
 535         * AAC
 536         * Mono/Stere: 768 + 4 halfword header
 537         */
 538        for (n = 0; n < FRAME_NUM; n++) {
 539                audio->in[n].data = data + 4;
 540                if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
 541                        data += (4 + (audio->channel_mode ? 2048 : 1024));
 542                else if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
 543                        data += (4 + 768);
 544        }
 545
 546        return audio_send_queue_rec(audio, &cmd, sizeof(cmd));
 547}
 548
 549static int audio_dsp_read_buffer(struct audio_in *audio, uint32_t read_cnt)
 550{
 551        audrec_cmd_packet_ext_ptr cmd;
 552
 553        memset(&cmd, 0, sizeof(cmd));
 554        cmd.cmd_id = AUDREC_CMD_PACKET_EXT_PTR;
 555        /* Both WAV and AAC use AUDREC_CMD_TYPE_0 */
 556        cmd.type = AUDREC_CMD_TYPE_0;
 557        cmd.curr_rec_count_msw = read_cnt >> 16;
 558        cmd.curr_rec_count_lsw = read_cnt;
 559
 560        return audio_send_queue_recbs(audio, &cmd, sizeof(cmd));
 561}
 562
 563/* ------------------- device --------------------- */
 564
 565static void audio_enable_agc(struct audio_in *audio, int enable)
 566{
 567        if (audio->agc_enable != enable) {
 568                audio->agc_enable = enable;
 569                if (audio->running)
 570                        audio_dsp_set_agc(audio);
 571        }
 572}
 573
 574static void audio_enable_ns(struct audio_in *audio, int enable)
 575{
 576        if (audio->ns_enable != enable) {
 577                audio->ns_enable = enable;
 578                if (audio->running)
 579                        audio_dsp_set_ns(audio);
 580        }
 581}
 582
 583static void audio_enable_tx_iir(struct audio_in *audio, int enable)
 584{
 585        if (audio->iir_enable != enable) {
 586                audio->iir_enable = enable;
 587                if (audio->running)
 588                        audio_dsp_set_tx_iir(audio);
 589        }
 590}
 591
 592static void audio_flush(struct audio_in *audio)
 593{
 594        int i;
 595
 596        audio->dsp_cnt = 0;
 597        audio->in_head = 0;
 598        audio->in_tail = 0;
 599        audio->in_count = 0;
 600        for (i = 0; i < FRAME_NUM; i++) {
 601                audio->in[i].size = 0;
 602                audio->in[i].read = 0;
 603        }
 604}
 605
 606static long audio_in_ioctl(struct file *file,
 607                                unsigned int cmd, unsigned long arg)
 608{
 609        struct audio_in *audio = file->private_data;
 610        int rc;
 611
 612        if (cmd == AUDIO_GET_STATS) {
 613                struct msm_audio_stats stats;
 614                stats.byte_count = atomic_read(&audio->in_bytes);
 615                if (copy_to_user((void *) arg, &stats, sizeof(stats)))
 616                        return -EFAULT;
 617                return 0;
 618        }
 619
 620        mutex_lock(&audio->lock);
 621        switch (cmd) {
 622        case AUDIO_START:
 623                rc = audio_in_enable(audio);
 624                break;
 625        case AUDIO_STOP:
 626                rc = audio_in_disable(audio);
 627                audio->stopped = 1;
 628                break;
 629        case AUDIO_FLUSH:
 630                if (audio->stopped) {
 631                        /* Make sure we're stopped and we wake any threads
 632                         * that might be blocked holding the read_lock.
 633                         * While audio->stopped read threads will always
 634                         * exit immediately.
 635                         */
 636                        wake_up(&audio->wait);
 637                        mutex_lock(&audio->read_lock);
 638                        audio_flush(audio);
 639                        mutex_unlock(&audio->read_lock);
 640                }
 641        case AUDIO_SET_CONFIG: {
 642                struct msm_audio_config cfg;
 643                if (copy_from_user(&cfg, (void *) arg, sizeof(cfg))) {
 644                        rc = -EFAULT;
 645                        break;
 646                }
 647                if (cfg.channel_count == 1) {
 648                        cfg.channel_count = AUDREC_CMD_STEREO_MODE_MONO;
 649                } else if (cfg.channel_count == 2) {
 650                        cfg.channel_count = AUDREC_CMD_STEREO_MODE_STEREO;
 651                } else {
 652                        rc = -EINVAL;
 653                        break;
 654                }
 655
 656                if (cfg.type == 0) {
 657                        cfg.type = AUDREC_CMD_TYPE_0_INDEX_WAV;
 658                } else if (cfg.type == 1) {
 659                        cfg.type = AUDREC_CMD_TYPE_0_INDEX_AAC;
 660                } else {
 661                        rc = -EINVAL;
 662                        break;
 663                }
 664                audio->samp_rate = convert_samp_rate(cfg.sample_rate);
 665                audio->samp_rate_index =
 666                  convert_dsp_samp_index(cfg.sample_rate);
 667                audio->channel_mode = cfg.channel_count;
 668                audio->buffer_size =
 669                                audio->channel_mode ? STEREO_DATA_SIZE
 670                                                        : MONO_DATA_SIZE;
 671                audio->type = cfg.type;
 672                rc = 0;
 673                break;
 674        }
 675        case AUDIO_GET_CONFIG: {
 676                struct msm_audio_config cfg;
 677                cfg.buffer_size = audio->buffer_size;
 678                cfg.buffer_count = FRAME_NUM;
 679                cfg.sample_rate = convert_samp_index(audio->samp_rate);
 680                if (audio->channel_mode == AUDREC_CMD_STEREO_MODE_MONO)
 681                        cfg.channel_count = 1;
 682                else
 683                        cfg.channel_count = 2;
 684                if (audio->type == AUDREC_CMD_TYPE_0_INDEX_WAV)
 685                        cfg.type = 0;
 686                else
 687                        cfg.type = 1;
 688                cfg.unused[0] = 0;
 689                cfg.unused[1] = 0;
 690                cfg.unused[2] = 0;
 691                if (copy_to_user((void *) arg, &cfg, sizeof(cfg)))
 692                        rc = -EFAULT;
 693                else
 694                        rc = 0;
 695                break;
 696        }
 697        default:
 698                rc = -EINVAL;
 699        }
 700        mutex_unlock(&audio->lock);
 701        return rc;
 702}
 703
 704static ssize_t audio_in_read(struct file *file,
 705                                char __user *buf,
 706                                size_t count, loff_t *pos)
 707{
 708        struct audio_in *audio = file->private_data;
 709        unsigned long flags;
 710        const char __user *start = buf;
 711        void *data;
 712        uint32_t index;
 713        uint32_t size;
 714        int rc = 0;
 715
 716        mutex_lock(&audio->read_lock);
 717        while (count > 0) {
 718                rc = wait_event_interruptible(
 719                        audio->wait, (audio->in_count > 0) || audio->stopped);
 720                if (rc < 0)
 721                        break;
 722
 723                if (audio->stopped) {
 724                        rc = -EBUSY;
 725                        break;
 726                }
 727
 728                index = audio->in_tail;
 729                data = (uint8_t *) audio->in[index].data;
 730                size = audio->in[index].size;
 731                if (count >= size) {
 732                        if (copy_to_user(buf, data, size)) {
 733                                rc = -EFAULT;
 734                                break;
 735                        }
 736                        spin_lock_irqsave(&audio->dsp_lock, flags);
 737                        if (index != audio->in_tail) {
 738                        /* overrun -- data is invalid and we need to retry */
 739                                spin_unlock_irqrestore(&audio->dsp_lock, flags);
 740                                continue;
 741                        }
 742                        audio->in[index].size = 0;
 743                        audio->in_tail = (audio->in_tail + 1) & (FRAME_NUM - 1);
 744                        audio->in_count--;
 745                        spin_unlock_irqrestore(&audio->dsp_lock, flags);
 746                        count -= size;
 747                        buf += size;
 748                        if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
 749                                break;
 750                } else {
 751                        pr_err("audio_in: short read\n");
 752                        break;
 753                }
 754                if (audio->type == AUDREC_CMD_TYPE_0_INDEX_AAC)
 755                        break; /* AAC only read one frame */
 756        }
 757        mutex_unlock(&audio->read_lock);
 758
 759        if (buf > start)
 760                return buf - start;
 761
 762        return rc;
 763}
 764
 765static ssize_t audio_in_write(struct file *file,
 766                                const char __user *buf,
 767                                size_t count, loff_t *pos)
 768{
 769        return -EINVAL;
 770}
 771
 772static int audio_in_release(struct inode *inode, struct file *file)
 773{
 774        struct audio_in *audio = file->private_data;
 775
 776        mutex_lock(&audio->lock);
 777        audio_in_disable(audio);
 778        audio_flush(audio);
 779        msm_adsp_put(audio->audrec);
 780        msm_adsp_put(audio->audpre);
 781        audio->audrec = NULL;
 782        audio->audpre = NULL;
 783        audio->opened = 0;
 784        mutex_unlock(&audio->lock);
 785        return 0;
 786}
 787
 788static struct audio_in the_audio_in;
 789
 790static int audio_in_open(struct inode *inode, struct file *file)
 791{
 792        struct audio_in *audio = &the_audio_in;
 793        int rc;
 794
 795        mutex_lock(&audio->lock);
 796        if (audio->opened) {
 797                rc = -EBUSY;
 798                goto done;
 799        }
 800
 801        /* Settings will be re-config at AUDIO_SET_CONFIG,
 802         * but at least we need to have initial config
 803         */
 804        audio->samp_rate = RPC_AUD_DEF_SAMPLE_RATE_11025;
 805        audio->samp_rate_index = AUDREC_CMD_SAMP_RATE_INDX_11025;
 806        audio->channel_mode = AUDREC_CMD_STEREO_MODE_MONO;
 807        audio->buffer_size = MONO_DATA_SIZE;
 808        audio->type = AUDREC_CMD_TYPE_0_INDEX_WAV;
 809
 810        rc = audmgr_open(&audio->audmgr);
 811        if (rc)
 812                goto done;
 813        rc = msm_adsp_get("AUDPREPROCTASK", &audio->audpre,
 814                                &audpre_adsp_ops, audio);
 815        if (rc)
 816                goto done;
 817        rc = msm_adsp_get("AUDRECTASK", &audio->audrec,
 818                           &audrec_adsp_ops, audio);
 819        if (rc)
 820                goto done;
 821
 822        audio->dsp_cnt = 0;
 823        audio->stopped = 0;
 824
 825        audio_flush(audio);
 826
 827        file->private_data = audio;
 828        audio->opened = 1;
 829        rc = 0;
 830done:
 831        mutex_unlock(&audio->lock);
 832        return rc;
 833}
 834
 835static long audpre_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 836{
 837        struct audio_in *audio = file->private_data;
 838        int rc = 0, enable;
 839        uint16_t enable_mask;
 840#if DEBUG
 841        int i;
 842#endif
 843
 844        mutex_lock(&audio->lock);
 845        switch (cmd) {
 846        case AUDIO_ENABLE_AUDPRE: {
 847                if (copy_from_user(&enable_mask, (void *) arg,
 848                                sizeof(enable_mask)))
 849                        goto out_fault;
 850
 851                enable = (enable_mask & AGC_ENABLE) ? 1 : 0;
 852                audio_enable_agc(audio, enable);
 853                enable = (enable_mask & NS_ENABLE) ? 1 : 0;
 854                audio_enable_ns(audio, enable);
 855                enable = (enable_mask & IIR_ENABLE) ? 1 : 0;
 856                audio_enable_tx_iir(audio, enable);
 857                break;
 858        }
 859        case AUDIO_SET_AGC: {
 860                if (copy_from_user(&audio->agc, (void *) arg,
 861                                sizeof(audio->agc)))
 862                        goto out_fault;
 863#if DEBUG
 864                pr_info("set agc\n");
 865                for (i = 0; i < AGC_PARAM_SIZE; i++) \
 866                        pr_info("agc_params[%d] = 0x%04x\n", i,
 867                                audio->agc.agc_params[i]);
 868#endif
 869                break;
 870        }
 871        case AUDIO_SET_NS: {
 872                if (copy_from_user(&audio->ns, (void *) arg,
 873                                sizeof(audio->ns)))
 874                        goto out_fault;
 875#if DEBUG
 876                pr_info("set ns\n");
 877                for (i = 0; i < NS_PARAM_SIZE; i++) \
 878                        pr_info("ns_params[%d] = 0x%04x\n",
 879                                i, audio->ns.ns_params[i]);
 880#endif
 881                break;
 882        }
 883        case AUDIO_SET_TX_IIR: {
 884                if (copy_from_user(&audio->iir, (void *) arg,
 885                                sizeof(audio->iir)))
 886                        goto out_fault;
 887#if DEBUG
 888                pr_info("set iir\n");
 889                pr_info("iir.num_bands = 0x%04x\n", audio->iir.num_bands);
 890                for (i = 0; i < IIR_PARAM_SIZE; i++) \
 891                        pr_info("iir_params[%d] = 0x%04x\n",
 892                                i, audio->iir.iir_params[i]);
 893#endif
 894                break;
 895        }
 896        default:
 897                rc = -EINVAL;
 898        }
 899
 900        goto out;
 901
 902out_fault:
 903        rc = -EFAULT;
 904out:
 905        mutex_unlock(&audio->lock);
 906        return rc;
 907}
 908
 909static int audpre_open(struct inode *inode, struct file *file)
 910{
 911        struct audio_in *audio = &the_audio_in;
 912        file->private_data = audio;
 913        return 0;
 914}
 915
 916static struct file_operations audio_fops = {
 917        .owner          = THIS_MODULE,
 918        .open           = audio_in_open,
 919        .release        = audio_in_release,
 920        .read           = audio_in_read,
 921        .write          = audio_in_write,
 922        .unlocked_ioctl = audio_in_ioctl,
 923};
 924
 925static struct file_operations audpre_fops = {
 926        .owner          = THIS_MODULE,
 927        .open           = audpre_open,
 928        .unlocked_ioctl = audpre_ioctl,
 929};
 930
 931struct miscdevice audio_in_misc = {
 932        .minor  = MISC_DYNAMIC_MINOR,
 933        .name   = "msm_pcm_in",
 934        .fops   = &audio_fops,
 935};
 936
 937struct miscdevice audpre_misc = {
 938        .minor  = MISC_DYNAMIC_MINOR,
 939        .name   = "msm_audpre",
 940        .fops   = &audpre_fops,
 941};
 942
 943static int __init audio_in_init(void)
 944{
 945        int rc;
 946        the_audio_in.data = dma_alloc_coherent(NULL, DMASZ,
 947                                               &the_audio_in.phys, GFP_KERNEL);
 948        if (!the_audio_in.data) {
 949                printk(KERN_ERR "%s: Unable to allocate DMA buffer\n",
 950                       __func__);
 951                return -ENOMEM;
 952        }
 953
 954        mutex_init(&the_audio_in.lock);
 955        mutex_init(&the_audio_in.read_lock);
 956        spin_lock_init(&the_audio_in.dsp_lock);
 957        init_waitqueue_head(&the_audio_in.wait);
 958        rc = misc_register(&audio_in_misc);
 959        if (!rc) {
 960                rc = misc_register(&audpre_misc);
 961                if (rc < 0)
 962                        misc_deregister(&audio_in_misc);
 963        }
 964        return rc;
 965}
 966
 967device_initcall(audio_in_init);
 968