Share Pastebin
Guest
Public paste!

Untitled

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